从 Javascript 中的事件侦听器调用访问对象的属性

IT技术 javascript events javascript-events event-handling
2021-02-20 07:28:09

下面我在 Javascript 中创建一个对象。在构造函数中,我正在设置一个事件侦听器。问题是当事件被触发时,找不到 this.prop,并打印出 undefined 。我该如何解决这个问题?

   var someObj = function someObj(){
       this.prop = 33;
        this.mouseMoving = function() { console.log(this.prop);}

        document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);

 }
6个回答

当事件处理程序被调用时,“this”不再引用“someObj”对象。您需要将“this”捕获到 mouseMoving 函数将捕获的局部变量中。

var someObj = function someObj(){
    this.prop = 33;
    var self = this;
    this.mouseMoving = function() { console.log(self.prop);}

    document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}

我假设“someObj 是一个构造函数,即打算用 as 调用new someObj(),否则“this”将是全局范围。

“this”关键字在 JavaScript 中可能会令人困惑,因为它的工作方式与其他语言不同。要记住的关键是它在调用函数绑定到调用对象,而不是在创建函数时。

有一个全局的“self”变量,但不存在冲突,因为局部变量会覆盖全局变量。如果它令人困惑,您可以使用其他东西。有些人使用“那个”,但我发现“这个”和“那个”是同一个对象是违反直觉的。
2021-04-19 07:28:09
var 名称可能不应该是“self”,因为它是一个预定义的 JS 变量。
2021-05-14 07:28:09

javascript 内置 Function.prototype.bind() 用于此目的。
例如:

var someObj = function someObj(){
       this.prop = 33;
        this.mouseMoving = function() { console.log(this.prop);}

        document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving.bind(this),true);

 }

更多关于绑定方法的信息:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

否则,您必须将对象 someObj 的引用传递给元素并在行中使用该引用:

console.log(this.referenceToObject.prop); //this references the DOM element in an event.
谢谢!我搜索了将近一个小时才找到这个。我知道这是可以做到的。这似乎是一种失传的技术。
2021-04-22 07:28:09
这是干净的解决方案,应该是公认的答案。
2021-05-04 07:28:09

来自Douglas CrockfordJavaScript: The Good Parts4.3 节

调用函数会暂停当前函数的执行,将控制和参数传递给新函数。除了声明的参数之外,每个函数还接收两个额外的参数:this 和 arguments。this 参数在面向对象编程中非常重要,它的值由调用模式决定。JavaScript 中有四种调用模式:方法调用模式、函数调用模式、构造函数调用模式和应用调用模式。模式在如何初始化奖金参数方面有所不同。

Crockford 继续解释每个模式中“this”的绑定,如下:

方法调用模式: 当函数作为对象的属性存储时,我们称其为方法。当一个方法被调用时, this 绑定到那个对象。

函数调用模式: 当使用此模式调用函数时, this 绑定到全局对象。这是语言设计的一个错误。

构造函数调用模式: 如果使用新前缀调用函数,则将创建一个新对象,该对象带有指向函数原型成员值的隐藏链接,并将绑定到该新对象。

Apply 调用模式: apply 方法让我们构造一个参数数组来调用一个函数。它还让我们选择 this 的值。apply 方法有两个参数。第一个是应该绑定到 this 的值。第二个是参数数组。

首先,您需要了解“this”在 JavaScript 中的工作原理。'this' 关键字的行为与它在其他语言(如 C# 或 JAVA)中的行为不同。阅读以下帖子以了解更多信息,

JavaScript 中“this”关键字行为的基本原理是什么?

一旦你理解了这一点,就像 Matthew 在他的代码中概述的那样,你可以保存对“this”的引用,并在 mouseMoving 函数中使用该引用。

虽然总的来说,我会建议您使用 JavaScript 框架(例如 jQuery、YUI、MooTools),它会为您处理这些问题。例如,在 Internet Explorer 中,您使用 addEvent 来附加事件而不是 addEventListenr。

不是问题。我认为让 JavaScript 新用户了解“this”是如何工作的很重要。除非他们理解“this”,否则我认为他们无法编写正确的 JavaScript 或调试。
2021-04-17 07:28:09
感谢您发布该链接。我一直在寻找答案,但找不到。
2021-05-09 07:28:09

您可以使用名为“me”的变量,以避免与全局 JavaScript 变量“self”冲突:

function someObj() {
  var me = this;
  this.prop = 33;

  this.mouseMoving = function() {
    alert(me.prop);
  }

  document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}