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.
精彩评论