如何避免“这个”引用DOM元素,并引用该对象 [英] How to avoid "this" refering to the DOM element, and refer to the object
问题描述
我遇到了一个无法解决的问题。
I have a problem that I can't work around.
上下文是:我想拥有一个继承链,以及一个属于的对象的方法这个继承必须是一个事件处理程序,同时能够到达对象属性。
The context is: I want to have an inheritance chain, and a method of objects that belong to this inheritance has to be a event handler, and at the same time be able to reach the object properties.
我试着编写没有new的JavaScript单词,而使用Object.create()代替一些继承层次结构。首先是这种方法。
I am giving a try to writing JavaScript without the "new" word, and using instead Object.create() with some inheritance hierarchy. So first this approach.
所以我有其他对象的蓝图(myProto),然后用Object.create创建对象(这样就没有了关闭我可以把这个
分配给
或 self
)。现在,当我使用这个对象的方法来处理例如div上的click事件时,这个
显然会引用DOM对象,而我失去了可能性访问我对象的属性。
So I have a blueprint for the rest of my objects (myProto), and then I create objects with Object.create (so that there is no closure where I can do the trick of assigning this
to that
or self
). Now, when I use a method of this object to handle, for instance, a click event on a div, this
obviously will refer to the DOM object, and I lose the posibility of accessing the properties of my object.
var myProto = {
init: function (name, value) {
this.name = name;
this.value = value;
return this;
},
someHandler: function (e) {
// Normally I would use this instead of e.target...
e.target.innerHTML = this.name + this.value; // This does not refer to the object.
}
};
var myObject = Object.create(myProto).init('myName', 'myValue');
document.getElementById('myDiv').onclick = myObject.someHandler;
这里的小提琴: http://jsfiddle.net/pgPHM/
现在是经典方法:如果我使用新的构造函数表单,很容易在闭包中分配它然后访问它,但是存在Constructor.prototype中的函数
And now the "classical" approach: If I was using the new Constructor form, it would be easy to assign this in the closure and then access it, but there is the problem that the functions in the Constructor.prototype
var Constructor = function (name, value) {
var self = this;
self.name = name;
self.value = value;
};
Constructor.prototype.someHandler = function () {/*self does not reach this here*/};
jsfiddle: http://jsfiddle.net/ZcG3J/2/
jsfiddle: http://jsfiddle.net/ZcG3J/2/
我真的不明白为什么JS对象没有真正的这个
或 self
或者在没有这些棘手的上下文,闭包等的情况下引用自己......
I really don't get why JS objects do not have a real this
or self
or whatever to refer to themselves without these tricky contexts, closures, etc...
基本上问题是:
如何使用对象的方法作为事件处理程序,仍然能够到达对象?
推荐答案
除了使用 new
, Javascript中的这个
是根据函数的调用方式设置的。以正确的方式调用它,这个
将是你想要的。我无法确定你在问题中试图解决的问题,但这是这个
的确定方式。
Except for when using new
, this
in Javascript is set by according to how a function is called. Call it the right way and this
will be what you want. I can't really tell what problem you're trying to solve in your question, but here's how this
is determined.
- 调用
obj.method()
-此
将设置为obj
在方法内部()
。 - 使用
函数.call()
或function.apply()
来控制这个
将是你自己。 - 进行正常的函数调用,例如
func()
和此
将被设置为全局对象或undefined
,具体取决于您是否处于严格模式。 - 使用
.bind()
(在现代浏览器中)创建一个函数存根,它将在内部自动使用.apply()
来绑定一个值这是函数的执行。 - 使用
new
调用构造函数时,这个
将被设置为构造函数内新创建的对象。 - 当你通过ac时allback函数作为任何函数调用的参数(例如
addEventListener()
,调用函数负责决定它想要的this
指向要设置的指针,不会绑定到您自己的对象。addEventListener()
将此
设置为导致该事件的DOM对象。
- Calling
obj.method()
-this
will be set toobj
inside ofmethod()
. - Use
function.call()
orfunction.apply()
to control whatthis
will be yourself. - Make a normal function call such as
func()
andthis
will be set to either the global object orundefined
depending upon whether you're in strict mode. - Use
.bind()
(in modern browsers) to create a function stub that will automatically use.apply()
internally to "bind" a value of this to the execution of the function. - When you call a constructor using
new
,this
will be set to the newly created object inside the constructor. - When you pass a callback function as an argument to any function call (such as
addEventListener()
, it is the calling function's responsibility to decide what it wants thethis
pointer to be set to and won't be bound to your own object.addEventListener()
setsthis
to be the DOM object that caused the event.
对于要对特定对象进行方法调用的事件处理程序,必须创建一种将方法调用与对象相关联的方法。您可以使用上面指定的 .bind()
或使用可以引用的保存值的匿名函数
在一个闭包中。
For event handlers that you want to be method calls on a particular object, you have to create a way to associate the method call with the object. You can either use .bind()
as specified above or use an anonymous function that can reference a saved value of this
in a closure.
var self = this;
document.addEventListener('keyup', function(e) {
self.handleKeys(e);
})
或者,使用 .bind()
:
document.addEventListener('keyup', this.handleKeys.bind(this));
仅供参考,这两种方法之间没有任何实际的功能差异,因为 .bind ()
只是创建一个闭包并执行第一个示例所做的操作,但是为你完成。
FYI, there's not any real functional difference between these two methods because .bind()
just creates a closure and does what the first example does, but does it for you.
这篇关于如何避免“这个”引用DOM元素,并引用该对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!