从JavaScript中的事件侦听器访问对象的属性
在下面,我在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);
}
Below I am creating an object in JavaScript. Within the constructor I am setting up an event listener. The problem is that when the event gets fired, this.prop
cannot be found, and undefined prints out. How do I solve this?
var someObj = function someObj(){
this.prop = 33;
this.mouseMoving = function() { console.log(this.prop);}
document.getElementById("someDiv").addEventListener('mousemove', this.mouseMoving, true);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用名为“ Me”的变量,以避免与全局JavaScript变量“ self”冲突:
You could use a variable named 'me', to avoid conflict with the global JavaScript variable 'self':
首先,您需要了解JavaScript中“此”的工作方式。 “此”关键字不会以其他语言(例如C#或Java)的行为行为。阅读以下帖子以了解更多信息,
JavaScript中“此”关键字的行为的理由是什么?
一旦您理解,正如Matthew在其代码中概述的那样,您可以保存对“此”的参考,并在Mousememoving函数中使用该引用。
尽管总的来说,我将建议您使用JavaScript框架(例如JQuery,Yui,Mootools),它将为您解决这些问题。例如,在Internet Explorer中,您使用addevent进行附加事件而不是AddeventListenr。
First, you need to understand how 'this' works in JavaScript. 'this' keyword doesn't behave how it behaves in other languages like C# or Java. Read following post to understand more,
What is the rationale for the behavior of the 'this' keyword in JavaScript?
Once you understand that, as Matthew outlined in his code, you can save reference to 'this' and use that reference inside the mouseMoving function.
Though overall, I will advise that you use a JavaScript framework (e.g. jQuery, YUI, MooTools) which will take care of these issues for you. E.g. In Internet Explorer, you use addEvent to attach event and not addEventListenr.
您的功能声明中有一些错别字。
您的Prop变量还定义为A “ public” 或“可见” 会员(通过使用此prop),这样做会迫使您存储的参考此来自外部函数(实际上是对对象实例的引用),作为函数的“ private” 成员(使用var),以获取创建对象的实例并阅读“公共” prop 成员。
您有一些重写此代码的替代方法:
或者您可以:
用 var 声明的变量可在主要构造函数内部声明的函数中获得可加入,此功能称为闭合。
You have some typos on your function declaration.
Your prop variable is also defined as a "public" or "visible" member (by using this.prop), doing so forces you to store the reference of this from the outer function (that is actually a reference to the object instance), as a "private" member of the function (using var) to get access the instance of the created object and read the "public" prop member.
You have some alternatives to rewrite this code:
Or you could:
The variables declared with var, are accesible to the functions declared inside of the major constructor function, this feature is known as Closures.
这个答案可能是当时最干净的解决方案;使用
bind()
允许侦听器从调用范围继承此
的值。但是现代JS具有更好的解决方案:箭头函数,它没有自己的
this
,因此会自动从其称为上下文中绑定一个函数。使用它,原始代码看起来像这样:
或者,使用现代类语法:
参考:箭头函数表达式在mdn上
This answer was likely the cleanest solution at the time; using
bind()
allows the listener to inherit the value ofthis
from the calling scope.But modern JS has a better solution: the arrow function, which does not have its own
this
, so automatically binds the one from its called context.Using that, the original code would look like this:
Or, using the modern class syntax:
Reference: Arrow function expressions on MDN
当事件处理程序被调用时,“this”不再引用“someObj”对象。您需要将“this”捕获到 mouseMoving 函数将捕获的局部变量中。
我假设“someObj 是一个构造函数,即打算使用
new someObj()
进行调用,否则“this”将是全局范围。“this”关键字在 JavaScript 中可能会造成混淆,因为它的工作方式与其他语言不同,要记住的关键是它是在调用函数时绑定到调用对象的,而不是在创建函数时。
When the event handler gets called, "this" no longer references the "someObj" object. You need to capture "this" into a local variable that the mouseMoving function will capture.
I'm assuming "someObj is a constructor, i.e. intended to be called with as
new someObj()
, otherwise "this" will be the global scope.The "this" keyword can be confusing in JavaScript, because it doesn't work the same way as in other languages. The key thing to remember is that it is bound to the calling object when the function is called, not when the function is created.
javascript 内置 Function.prototype.bind() 就是用于此目的。
例如:
有关绑定方法的更多信息,请参见: https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
否则,您必须将对象 someObj 的引用传递给元素并在行中使用该引用:
The javascript built-in Function.prototype.bind() is intended for this purpose.
For example:
More on the bind method here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
Other wise you have to pass a reference of the object someObj to the element and use that reference in the line:
JavaScript的第4.3节: Douglas Crockford 的好部分:
克罗克福德(Crockford)继续解释“此”中每种模式的绑定,如下所示:
方法调用模式:
将函数作为对象的属性存储时,我们称其为方法。调用方法时,这将绑定到该对象。
功能调用模式:
当使用此模式调用函数时,这将绑定到全局对象。这是语言设计的错误。
构造函数调用模式:
如果使用新前缀调用函数,则将创建一个新对象,并以隐藏的链接指向该函数原型成员的值,这将绑定到该新对象。
应用调用模式:
应用方法使我们可以构造一个参数来调用函数。它还使我们可以选择它的价值。应用方法采用两个参数。第一个是应与此绑定的值。第二个是参数数组。
From Section 4.3 of JavaScript: The Good Parts by Douglas Crockford:
Crockford continues to explains the binding of 'this' in each of these patterns, as follows:
The Method Invocation Pattern:
When a function is stored as a property of an object, we call it a method. When a method is invoked, this is bound to that object.
The Function Invocation Pattern:
When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language.
The Constructor Invocation Pattern:
If a function is invoked with the new prefix, then a new object will be created with a hidden link to the value of the function's prototype member, and this will be bound to that new object.
The Apply Invocation Pattern:
The apply method lets us construct an array of arguments to use to invoke a function. It also lets us choose the value of this. The apply method takes two parameters. The first is the value that should be bound to this. The second is an array of parameters.