[英]How to avoid “this” refering to the DOM element, and refer to the object
我有一个无法解决的问题。
上下文是:我想拥有一个继承链,并且属于该继承的对象的方法必须是事件处理程序,并且同时能够访问对象属性。
我正在尝试编写不带“新”字的JavaScript,并改为将Object.create()与某些继承层次结构一起使用。 所以首先是这种方法。
所以,我有我的其余对象(myProto)的蓝图,然后我创建的Object.create对象(所以没有封在那里我可以做到分配的把戏this
要that
或self
)。 现在,当我使用该对象的方法来处理例如div上的click事件时, this
显然将引用DOM对象,并且我失去了访问对象属性的可能性。
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表单,则很容易在闭包中分配它然后访问它,但是存在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/
我真的不明白为什么JS对象在没有这些棘手的上下文,闭包等情况下没有真正的this
或self
或任何引用自己的东西...
基本上,问题是:
如何使用对象的方法作为事件处理程序,并且仍然能够访问该对象?
除了使用时new
, this
在Javascript中是按照函数是如何被调用设置。 称呼正确, this
就是您想要的。 我真的不能告诉你想在你的问题来解决什么问题,但在这里是如何this
是确定的。
obj.method()
- this
将在method()
内部设置为obj
。 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()
只是创建了一个闭包,并且执行了第一个示例中的操作,但是为您完成了此操作。
简单。 如果某个函数被称为方法而不是“裸”,则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);
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/
是否按您想要的结构?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.