我正在尝试将javascript对象绑定到事件侦听器,这就是我要做的事情: (这是一个简化的例子,但它使用了我感兴趣的模式)
function foo(x){
this.x = x;
}
foo.prototype = {
'bar': function(){
// do something with this.x
},
'events': function(){
$(document).on('custom_event', function(event, x){
var G = new foo(x);
G.bar();
});
}
};
(function(){
var G = new foo();
G.events();
})();
因此,在运行自调用匿名函数之后,每次触发custom_event
时,都会调用我的foo对象的bar方法。
问题:
从我的foo对象的事件处理程序中调用new foo(x)
时,是否会导致事件监听器的重复?
据我了解,属于某个对象的prototype
方法只创建一次,而调用new foo()
只会影响this.x
。如果我是正确的,我很困惑为什么有必要在new
的{{1}}方法中使用事件监听器中的foo
来使用附加到{{1的原型方法}}
我错过了什么?
答案 0 :(得分:2)
您似乎对new
运算符的用法和效果感到困惑。我引自You Don't Know JS, this & object prototypes:
当一个函数在其前面调用
new
时,也称为构造函数调用,以下内容自动完成:
- 创造一个全新的物体(又名,构建)凭空而来
- 新构建的对象为
[[Prototype]]
- 已链接- 将新构造的对象设置为该函数调用的
this
绑定- 除非函数返回其自己的备用对象,否则
醇>new
调用的函数调用将自动返回新构造的对象。
确保你理解得那么好。关于你的问题:
从我的foo对象的事件处理程序中调用
new foo(x)
时,是否会导致事件监听器的重复?
没有。你使用new foo(x)
做的是使用foo
函数作为构造函数,所以你只是创建一个新的,原型链接的对象(类似于{}
),然后在里面执行代码foo
,新对象为this
。因此,除了属性x
之外,这将导致几乎为空的对象。您只是在events
函数内设置事件监听器!
据我了解,属于某个对象的
prototype
方法只创建一次,而调用new foo()
只会影响this.x
。如果我是正确的,我很困惑为什么有必要在new
的{{1}}方法中使用事件监听器中的foo
来使用附加到{{1的原型方法}}
它们被定义一次,在您称为“原型”的对象上(实际上只是函数events
上的foo
属性),是的。并且没有必要在这里使用prototype
,所有你正在做的就是在已经存在的foo
对象的函数内创建一个一次性new
对象。
您可能想要做的不是担心在构造函数中设置foo
,而是在调用foo
之前在事件处理程序中设置:
this.x
你在这里遇到的问题是,事件处理程序上下文中的bar()
很可能被jQuery设置/覆盖,而不是指向你想要的“something.on('custom_event', function(e, x) {
this.x = x;
this.bar();
});
对象”指向。要解决此问题,您需要在设置事件处理程序(即this
函数)时词法捕获 foo
:
this
或events
您要引用的“events: function(){
var self = this;
$(document).on('custom_event', function(event, x){
self.x = x;
self.bar();
});
}
对象”的回调处理程序中的bind
:
this
有关这方面的一些解释,请参阅MDN上的Function.prototype.bind。
进一步说明:我不确定你的自定义事件是什么,但你正在每个事件处理程序内部监听整个foo
。如果你有与每个events: function(){
$(document).on('custom_event', (function(event, x){
this.x = x;
this.bar();
}).bind(this));
}
对象相对应的DOM元素,你应该在这些特定的DOM元素上设置这些事件处理程序。