Cha*_*ins 4 javascript oop events scope
我把这种情况的缺乏理解归结为这个小问题.到目前为止,我认为这是我所知道的:
我有一个对象myDog(一个全局变量).Dog有一个成员变量el是一个html元素; 因为它是一个元素,我可以添加事件监听器.因此,当您单击时myDog.el,它会向控制台记录this.name和的值myDog.name.正如预期的那样,范围this.name是未定义的并且myDog.name是'tye'.当由click事件监听器调用时,this内部Dog.speak引用被单击的元素,即成员变量el,而不是对象Dog.由于它myDog是一个全局变量,因此无论函数的范围如何,它都可以进行备份,并且可以myDog.name很好地完成.
见下面的代码:
function Dog(name,id) {
this.name = name ? name : "spot";
this.id = id ? id : "dog";
this.el = document.getElementById(this.id); // given there is a div with a matching
this.el.addEventListener("click",this.speak); // ignore IE for simplicity (attachEvent has its own 'this' scope issues)
}
Dog.prototype = {
speak: function() {
console.log("this.name: "+this.name+"\nmyDog.name: "+myDog.name);
}
};
var myDog = new Dog("tye","dog1");
Run Code Online (Sandbox Code Playgroud)
所以...我的问题是
1)将对象附加到html元素的一些策略是什么,这样我可以this.el回到myDog(this.el所有者)而myDog不是全局变量?
2)在这种情况下全局变量是否是必要的邪恶?如果是这样,在这种情况下优雅使用它们的优秀策略是什么?例如,如果我想要100只狗实例化怎么办?我将如何处理所有这些全局变量Dog.speak?
如果您想玩它,这是一个jsfiddle版本:http://jsfiddle.net/chadhutchins/Ewgw5/
小智 6
"1)将对象附加到html元素的策略是什么......"
既然你正在使用.addEventListener(),我建议利用它的一个功能,很少有人似乎知道...让你的Dog对象实现EventListener接口.
这在您的Dog数据及其相关元素之间建立了非常干净的关系.
只需要进行微小的更改.代码首先......解释如下.
演示: http : //jsfiddle.net/Ewgw5/1/
function Dog(name,id) {
this.name = name ? name : "spot";
this.id = id ? id : "dog";
this.el = document.getElementById(this.id);
// ---------------------------------v----no function!
this.el.addEventListener("click", this);
}
Dog.prototype = {
// Implement the `EventListener` interface
handleEvent: function(event) {
switch (event.type) {
case "click": return this.speak();
}
},
speak: function() {
console.log("this.name: "+this.name+"\nmyDog.name: "+myDog.name);
}
};
var myDog = new Dog("tye","dog1");
Run Code Online (Sandbox Code Playgroud)
所以我所做的只是传递this构造函数addEventListener()而不是传递一个函数,然后我添加了一个handleEvent()方法Dog.prototype.
现在,当一个"click"事件发生时,它将调用该handleEvent()方法.该this方法的值将是您的Dog实例.所以,从那里你可以调用你需要的任何方法.
因为您将元素作为属性this,所以您可以通过它访问元素this.el.但这在技术上甚至不是必需的,因为元素也可以通过event对象获得event.currentTarget.
"2)在这种情况下全局变量是必要的邪恶......"
谢天谢地!
此行为应该是您的垫片的一部分.addEventListener().