Javascript对原型的新影响

Javascript new effect on prototype

本文关键字:影响 新影响 原型 Javascript      更新时间:2023-09-26

我正在尝试将一个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。如果我是正确的,我会感到困惑,为什么必须在fooevents方法中的事件侦听器中使用new,才能使用附加到foo的原型方法。

我错过了什么?

您似乎主要对new运算符的用法和效果感到困惑。我引用了You Don't Know JS,这个&对象原型:

当函数前面有new(也称为构造函数调用)时,会自动执行以下操作:

  1. 一个全新的物体凭空产生
  2. 新构建的对象是[[Prototype]]链接的
  3. 新构建的对象被设置为该函数调用的this绑定
  4. 除非函数返回自己的备用对象,否则new调用的函数调用将自动返回新构造的对象

确保你能很好地理解这一点。关于您的问题:

当从我的foo对象的事件处理程序中调用new foo(x)时,它是否会导致事件侦听器的重复?

没有。使用new foo(x)的方法是使用foo函数作为构造函数,因此您只创建一个新的原型链接对象(类似于{}),然后在foo中执行代码,将该新对象作为this。因此,除了属性x之外,这将导致一个几乎为空的对象。您只是在events函数中设置事件侦听器!

我的理解是,属于一个对象的prototype方法只创建一次,而调用new foo()只会影响this.x。如果我是正确的,我会感到困惑,为什么需要在fooevents方法中的事件侦听器中使用new才能使用foo附带的原型方法。

它们被定义一次,在您称为"原型"的对象上(实际上只是函数fooprototype属性),是的。这里没有必要使用new,您所要做的只是在已经存在的foo对象的函数中创建一个一次性的foo对象。

在调用bar():之前,您可能不需要担心在构造函数中设置this.x,而是在事件处理程序中设置

something.on('custom_event', function(e, x) {
  this.x = x;
  this.bar();
});

您在这里会遇到的问题是,事件处理程序上下文中的this很可能会被jQuery设置/覆盖,而不是指向您想要指向的"foo对象"。为了避免这个问题,您需要在设置事件处理程序(即events函数)时用词法捕获this

events: function(){
    var self = this;
    $(document).on('custom_event', function(event, x){
        self.x = x;
        self.bar();
    });
}

bind回调处理程序中要引用的"foo对象"的this

events: function(){
    $(document).on('custom_event', (function(event, x){
        this.x = x;
        this.bar();
    }).bind(this));
}

请参阅MDN上的Function.prototype.bind,了解它的作用。


进一步注意:我不确定您的自定义事件到底是什么,但您正在监听每个事件处理程序中的整个$(document)。如果您有对应于每个foo对象的DOM元素,那么您应该在这些特定的DOM元素上设置这些事件处理程序。