开发者

jQuery + extending Object.prototype = "c.replace is not a function"

I am using jQuery 1.5 in my open source project and following line is also present in my own Javascript code:

/**
 * Object.isEmpty()
 *
 * @returns {Boolean}
 */
Object.prototype.isEmpty = function ()
{
    /**
     * @deprecated Since Javascript 1.8.5
     * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object
     */
    if ( this.__count__ !== undefined )
    {
        return this.__count__ === 0 ? true : false;
    }

    /* Less-aesthetic method, if above method fails */
    for ( var property in this )
    {
        if ( this.hasOwnProperty(property) )
        {
            return false;
        }
    }
    return true;
};

which just extends Object.prototype adding isEmpty() method to it [that checks whether the object is empty or not). Because of this addition, I am getting "c.replace is not a function" error in my Firebug console; and my research on the web lead me to jQuery bug tracker messa开发者_运维百科ge, where I "learned" that extending Object.prototype not only breaks jQuery, but also is bad coding practice. My question is, why?


ECMA-262 5th Edition (and JavaScript 1.8.5) has ways to do it through the Object.defineProperty and Object.defineProperties methods, by setting the enumerable field of the property to false. That is available in Chrome 5, Safari 5, Firefox 4 and Internet Explorer 9 or any recent server side implementation that uses V8 (like Node.js).


Basically, that because extending Object.prototype breaks the for ... in idiom.

In Javascript, if you have an object:

var obj = { "foo": 0, "bar": 42 };

You can iterate over its members by doing:

for (var key in obj) {
    // Do Something.
}

Extending Object.prototype will result in the extended members being present in all object instances, so the code above would iterate over more keys than foo and bar, with probably unexpected results.

You can find a fiddle demonstrating the problem here.


1) How to add (extend) additional methods (not properties) to Object?

As long as third party code is running on your page you shouldn't.

2) If you can distinguish immediate children of your object from global ones, with help of hasOwnProperty(), why it is a bad coding?

Because there's a likelihood that other programmers are lazy, and you break their code. It is a good practice not to modify what you don't own. Object.prototype is one of these things.

Use MyLib.isEmpty(obj), or isEmpty(obj) inside your own scope so there's no chance to collide.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜