javascript - 在原型(prototype)中进行事件绑定(bind)是否明智,为什么它的上下文会丢失?

标签 javascript jquery prototype jquery-events

在为网页创建模块化 JavaScript 代码时,我经常需要将事件附加到例如纽扣。

采用以下示例代码,通常在 AMD 模块中找到:

define(function(require) {

    var MyObject = function(ele) {
        this.ele = ele;
    }

    MyObject.prototype = {
        myfunct: function() {
            console.log('myfunct called');
        }
    }

    return MyObject;

});

稍后在页面上我会做:

$(document).ready(function() {
    var button = $('#button'),
        myobj = new MyObject(button);

    button.click(function() {
        myobj.myfunct();
    });
});

这行得通,但我觉得还是有点不干净。

例如,我需要在全局命名空间中创建至少一个变量来将一个函数绑定(bind)到一个按钮。此外,当页面上有许多 JavaScript 驱动的交互时,代码会变得困惑——这是我最初想通过使用模块化 JavaScript 来解决的问题。

这就是为什么我的想法是在原型(prototype)内部绑定(bind)事件:

var MyObject = function(ele) {
    self = this;
    this.element = ele; 

    this.init();
}

MyObject.prototype = {
    init: function() {        
        $(this.element).click(function() {
           self.myfunct();
        });
    },
    myfunct: function() {
        console.log('myfunct called');
    }
}

这样,模块外部的代码将如下所示:

$(document).ready(function() {
    var button = $('#button'),
        myobj = new MyObject(button);

});

将事件绑定(bind)移动到原型(prototype)中是否明智?如果是这样,我这样做的方式是否可以,或者是否有使用 init() 的方法?

此外,我注意到当页面上有两个按钮时,一些上下文会丢失 – self 总是引用 MyObj 的最后一个实例。

为什么会这样——我认为使用 self = this; 可以阻止上下文?

Fiddle

最佳答案

好的,首先是 self 发生了什么。

用这一行:

self = this;

您正在创建一个名为 self 的全局变量,每次调用构造函数时都会覆盖该变量。如果您使用严格模式,这很容易被检测到。此外,如果您正确使用局部变量,您的原型(prototype)将不知道什么是 self,因此您尝试在原型(prototype)中使用 self 是错误的。

我认为你的两种方法都存在问题:

  • 第一种方法需要在您的 MyObject 类型之外进行太多手动工作。
  • 第二种方法(如果它工作正常)将事件附加到按钮作为调用构造函数的副作用。这会让使用您的 API 的人感到困惑,因为他们希望构造函数创建一个对象,而不是修改其他现有对象。

作为补救措施,我建议采用以下方法:

var MyObject = function(ele) {
    this.element = ele; 
}

MyObject.prototype = {
    attachEvents: function() {        
        var self = this;
        $(this.element).click(function() {
           self.myfunct();
        });
    },
    myfunct: function() {
        console.log('myfunct called');
    }
};

$(document).ready(function() {
    var button = $('#button'),
        myobj = new MyObject(button);

    myobj.attachEvents();
});

这需要实例化 MyObject 的人执行一个额外的步骤,但它清楚地传达了将事件附加到 myobj 的封装元素的意图。它也不需要使用 MyObject 的人来执行您的第一种方法的复杂操作。

关于javascript - 在原型(prototype)中进行事件绑定(bind)是否明智,为什么它的上下文会丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28386384/

相关文章:

javascript - Mongoose 文本搜索未返回任何结果

javascript - 根据request.body创建JSON对象

javascript - 我只能捕获 Node.js 脚本的第一行输出

javascript - 如何动态创建 '@-Keyframe' CSS动画?

javascript - 我如何在原型(prototype)工作中获得 "this = this"

javascript - 如何在 ibm worklight 中创建 In app browser

jquery - 如何将 JSON 数组字段传递给 Spring REST Controller

javascript - 通过单击目标循环渐变方向

javascript - 在原型(prototype)的构造函数中初始化属性时获取 'undefined'

javascript - 哪些 JavaScript 对象的原型(prototype)中有 addEventlistener?