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

访问对象';Javascript中的事件侦听器调用的s属性,javascript,events,javascript-events,event-handling,Javascript,Events,Javascript Events,Event Handling,下面我用Javascript创建一个对象。在构造函数中,我正在设置一个事件侦听器。问题是,当事件被激发时,找不到this.prop,并且输出undefined。我如何解决这个问题 var someObj = function someObj(){ this.prop = 33; this.mouseMoving = function() { console.log(this.prop);} document.getElementById("s

下面我用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);

 }

当调用事件处理程序时,“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中可能会令人困惑,因为它的工作方式与其他语言不同。需要记住的关键是,在调用函数时,它绑定到调用对象,而不是在创建函数时。

JavaScript内置函数。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);

 }
有关绑定方法的更多信息,请参见:

另一方面,您必须将对象someObj的引用传递给元素,并在行中使用该引用:

console.log(this.referenceToObject.prop); //this references the DOM element in an event.

您的函数声明有一些拼写错误

您的prop变量也被定义为“public”或“visible”成员(通过使用this.prop),这样做会迫使您将外部函数对此的引用(实际上是对对象实例的引用)存储为函数的“private”成员(使用var)以访问所创建对象的实例并读取“public”“道具成员

您可以选择重写此代码:

function someObj (){
    var self = this;
    this.prop = 33;
    this.mouseMoving = function() { alert(self.prop);} // You access the current
                                                       // instance, stored in *self*
                                                       // since *this*, inside the 
                                                       // function, is in another 
                                                       // context.
    //...
}

var mySomeObj = new someObj(); // Object instantiation
或者你可以:

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

    //...
}
var mySomeObj = new someObj(); // Object instantiation

使用var声明的变量可访问主构造函数中声明的函数,此功能称为。

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

一旦您理解了这一点,正如Matthew在他的代码中所概述的,您就可以保存对“this”的引用,并在mouseMoving函数中使用该引用


尽管总体而言,我建议您使用JavaScript框架(例如jQuery、YUI、MooTools),它将为您解决这些问题。例如,在Internet Explorer中,使用addEvent来附加事件,而不是addEventListenr

来自Douglas Crockford的《JavaScript:好的部分》第4.3节:

调用函数将挂起 当前功能的执行, 将控件和参数传递给 新功能。除了 声明的参数,每个函数 接收两个附加参数: 这是一个有争议的问题。此参数的值为 这在面向对象中非常重要 编程,其价值是 由调用模式决定。 有四种调用模式 在JavaScript中:方法调用 模式,函数调用 模式,构造函数调用 模式和应用调用 图案不同的模式有不同的方式 奖金参数是 初始化

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

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

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

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

应用调用模式:
apply方法允许我们构造一个参数数组,用于调用函数。它还允许我们选择这个的值。apply方法采用两个参数。第一个是应该绑定到此的值。第二个是参数数组。

可以使用名为“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);
}

变量名可能不应该是“self”,因为它是一个预定义的JS变量。有一个全局“self”变量,但没有冲突,因为局部变量覆盖全局变量。如果让人困惑,你可以用别的东西。有些人用“那个”,但我觉得“这个”和“那个”是同一个对象是违反直觉的。谢谢你发布这个链接。我一直在寻找答案,但没找到。没问题。我认为告知新的JavaScript用户“这”是如何工作的是很重要的。除非他们理解“这一点”,否则我认为他们将无法编写正确的JavaScript或调试。谢谢!我找了将近一个小时才找到这个。我知道这是可以做到的。这似乎是一个失败的技术。这是一个干净的解决方案,应该是公认的答案。