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

时间:2009-07-04 04:35:13

标签: javascript events javascript-events event-handling

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

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

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

 }

6 个答案:

答案 0 :(得分:21)

当调用事件处理程序时,“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是一个构造函数,即打算用new someObj()调用,否则”this“将成为全局范围。

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

答案 1 :(得分:8)

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.

答案 2 :(得分:5)

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

  

调用函数暂停   执行当前功能,   将控制和参数传递给   新功能。除了   声明参数,每个函数   接收另外两个参数:   这和争论。这个参数   在面向对象方面非常重要   编程,它的价值在于   由调用模式决定。   有四种调用模式   在JavaScript中:方法调用   模式,函数调用   模式,构造函数调用   模式和应用调用   图案。模式因人而异   这是奖金参数   初始化。

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

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

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

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

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

答案 3 :(得分:3)

首先,您需要了解'this'在JavaScript中的工作原理。 'this'关键字不会像C#或JAVA等其他语言那样表现。阅读以下帖子以了解更多信息,

What is the rationale for the behavior of the 'this' keyword in JavaScript?

一旦你理解了,正如Matthew在他的代码中所概述的那样,你可以保存对'this'的引用,并在mouseMoving函数中使用该引用。

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

答案 4 :(得分:3)

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

答案 5 :(得分:0)

你的功能声明上有一些拼写错误。

您的prop变量也被定义为“public”“visible”成员(通过使用this.prop),这样做会强制您存储引用 this 来自外部函数(实际上是对象实例的引用),作为函数的“private”成员(使用var)来获取访问实例的创建的对象并阅读“public”prop 成员。

您可以选择重写此代码:

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 声明的变量可以访问主要构造函数内部声明的函数,此功能称为Closures