开发者

What is a better approach to prototype for multiple types

Ignoring the fact that this is implemented by many frameworks..

What is the best way to prototype for multiple object types.

For example, Should I write:

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);
    }
};

or

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(eventTyp开发者_运维知识库e, fn, false);
        }
    }
}


Big red flag: never extend Object.prototype! It breaks for (x in y) (or at least people's expectations of how it works).

In the general case, however, it's better to extend the individual types' prototypes rather than try to find a common base and perform reflection checks. There are two basic reasons to do this.

First, JavaScript is a dynamically typed language, so you should generally prefer duck typing and basic inheritance over instanceof and reflection. In many cases, there is a small performance benefit, but mainly this is so you don't spend time fighting the language.

Second, this type of method switching implies connections between the switched methods which do not necessarily exist. In your sample code, this can be seen in the NodeList version. Conceptually, a list shouldn't be binding anything; if it has a bind method, it should simply translate into calling the bind method on each of its elements. This ensures that if any extra steps need added to binding in the future (say, workarounds for old, non-DOM-conforming browsers…), you only need to do so in one place.

But looking at it in terms of type switching in the "same function" gives the false impression that both Element.bind and NodeList.bind should work the same way — by calling addEventListener. Here's how I'd implement it:

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);
    }
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜