什么是更好的多种类型的原型方法

时间:2011-09-28 20:15:35

标签: javascript function

忽略这是由 许多 框架实现的事实..

为多种对象类型制作原型的最佳方法是什么。

例如,我应该写:

Element.prototype.bind = function(eventType, fn) {
    this.addEventListener(eventType, fn, false);
};
NodeList.prototype.bind = function(eventType, fn) {
    for (var i = 0, l = this.length; i < l; i++) {
        this[i].addEventListener(eventType, fn, false);
    }
};

Object.prototype.bind = function(eventType, fn) {
    if (this instanceof Element) {
        this.addEventListener(eventType, fn, false);
    } else if (this instanceof NodeList) {
        for (var i = 0, l = this.length; i < l; i++) {
            this[i].addEventListener(eventType, fn, false);
        }
    }
}

1 个答案:

答案 0 :(得分:3)

红旗:从不延长Object.prototype!它会打破for (x in y)(或者至少是人们对它如何运作的期望)。

但是,在一般情况下,最好扩展单个类型的原型,而不是尝试查找公共基础并执行反射检查。这样做有两个基本原因。

首先,JavaScript是一种动态类型语言,因此您通常应该优先选择鸭子类型和基本继承而不是instanceof和反射。在许多情况下,有一个小的性能优势,但主要是因为你不花时间与语言作斗争。

其次,这种类型的方法切换意味着切换方法之间的连接不一定存在。在您的示例代码中,可以在NodeList版本中看到。从概念上讲,列表不应该绑定任何东西;如果它有bind方法,它应该简单地转换为在每个元素上调用bind方法。这确保了如果将来需要为绑定添加任何额外步骤(例如,旧的,不符合DOM的浏览器的变通方法......),您只需要在一个地方执行此操作。

但是,根据“相同功能”中的类型切换来看待它会给人以错误的印象:Element.bindNodeList.bind应该以相同的方式工作 - 通过调用addEventListener。以下是我实现它的方法:

Element.prototype.bind = function(eventType, fn) {
    this.addEventListener(eventType, fn, false);
};

NodeList.prototype.bind = function(eventType, fn) {
    for (var i = 0, l = this.length; i < l; i++) {
        this[i].bind(eventType, fn);
    }
};