简体   繁体   中英

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 message , 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM