我遇到了一个无法解决的问题。
上下文是:我想拥有一个继承链,属于这个继承的对象的方法必须是一个事件处理程序,同时能够到达对象属性。
我试着编写没有“new”字的JavaScript,而是使用Object.create()和一些继承层次结构。首先是这种方法。
所以我对其余的对象(myProto)有一个蓝图,然后用Object.create创建对象(这样就没有闭包,我可以把this
分配给{{ 1}}或that
)。现在,当我使用此对象的方法来处理div上的click事件时,self
显然会引用DOM对象,并且我失去了访问对象属性的可能性。 / p>
this
这里的小提琴:http://jsfiddle.net/pgPHM/
现在是“经典”方法:如果我使用的是新的构造函数表单,那么很容易在闭包中分配它然后访问它,但是存在Constructor.prototype中的函数的问题
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;
jsfiddle:http://jsfiddle.net/ZcG3J/2/
我真的不明白为什么JS对象没有真正的var Constructor = function (name, value) {
var self = this;
self.name = name;
self.value = value;
};
Constructor.prototype.someHandler = function () {/*self does not reach this here*/};
或this
或者在没有这些棘手的上下文,闭包等的情况下引用自己......
基本上问题是:
如何将对象的方法用作事件处理程序,并且仍然能够到达对象?
答案 0 :(得分:2)
除了使用new
时,Javascript中的this
是根据函数的调用方式设置的。以正确的方式调用它,this
将是您想要的。我无法确定你在问题中想要解决的问题,但是this
是如何确定的。
obj.method()
内拨打this
- obj
将设置为method()
。function.call()
或function.apply()
来控制自己this
的内容。func()
和this
将被设置为全局对象或undefined
,具体取决于您是否处于严格模式。.bind()
(在现代浏览器中)创建一个函数存根,它将在内部自动使用.apply()
将此值“绑定”到函数的执行中。new
调用构造函数时,this
将设置为构造函数内新创建的对象。addEventListener()
时,调用函数有责任决定它需要将this
指针设置为并赢得'绑定到您自己的对象。addEventListener()
将this
设置为导致该事件的DOM对象。对于要对特定对象进行方法调用的事件处理程序,必须创建一种将方法调用与对象关联的方法。您可以使用上面指定的.bind()
或使用可以在闭包中引用保存的this
值的匿名函数。
var self = this;
document.addEventListener('keyup', function(e) {
self.handleKeys(e);
})
或使用.bind()
:
document.addEventListener('keyup', this.handleKeys.bind(this));
仅供参考,这两种方法之间没有任何真正的功能差异,因为.bind()
只是创建一个闭包并执行第一个示例所做的事情,但是它适合您。
答案 1 :(得分:2)
简单。如果函数被称为方法而不是“裸”,则this
始终引用最后一个点之前的单词。所以而不是:
document.getElementById('myDiv').onclick = myObject.someHandler;
// You're just passing the function here, not calling it.
// It will be called by the onclick handler so `this` is changed
这样做:
document.getElementById('myDiv').onclick = function(){
myObject.someHandler();
// Here, you're actually calling it. So this is the word
// before the last dot. Which is myObject
}
在更现代的JavaScript中,您当然可以使用bind
:
document.getElementById('myDiv').onclick = myObject.someHandler.bind(myObject);
答案 2 :(得分:1)
你的jsfiddle中的第一个问题是self是Constructor的局部变量,它在函数外部不可用。您对以下代码的看法如下:
var Constructor = function(name, value) {
var self = this;
self.name = name;
self.value = value;
self.someHandler = function(e) {
e.target.innerHTML = self.name + self.value; // self undefined
}
return self;
};
var myObject = Constructor('myName', 'myValue');
document.getElementById('myDiv').onclick = myObject.someHandler;
JsFiddle - > http://jsfiddle.net/ZcG3J/4/
它的结构是否符合您的要求?