Prototyping Object in Javascript breaks jQuery?

I have added a simple .js file to my page that has some pretty mundane common-task sort of functions added to the Object and Array prototypes.

Through trial and error, I've figured out that adding any function to Object.prototype , no matter it's name or what it does causes Javascript errors in jQuery:

The culprit?

Object.prototype.foo = function() {
    /*do nothing and break jQuery*/
};

The error I'm getting line 1056 of jquery-1.3.2.js , in the attr:function { } declaration:

/*Object doesn't support this property or method*/
name = name.replace(/-([a-z])/ig, function(all, letter) {
            return letter.toUpperCase();
        });

Apparently G.replace is undefined.

While it's obvious that there's something I'm just not wrapping my head around with prototyping, I'm failing miserably to figure out what it is.

To be clear, I'm not looking for a workaround, I have that handled... what I'm looking for is an answer to Why? . Why does adding a function to Object.prototype break this bit of code?


You should never extend Object.prototype . It does far more than break jQuery; it completely breaks the "object-as-hashtables" feature of Javascript. Don't do it.

You can ask John Resig, and he'll tell you the same thing.


If it's simply a case of messing up for...in loops, can't you use Object.defineProperty to add your fn without making it enumerable?

So:

Object.defineProperty(Object.prototype, "foo", { 
    value: function() {
        // do stuff
    },
    enumerable : false
});

Seems to work for me. Would this still be considered bad form?


I agree, adding something to Object.prototype demands caution and should be avoided. Look for other solutions such as:

Adding it to Object and then accessing it with a call or apply , as needed. For example:

Object.foo = function () { return this.whatever()}

Then call that on an object by:

Object.foo.call(Objname);  // this invokes the function as though it were a
                           // method of Objname.  That is, its like Objname.foo()

For fun, you can add the following (yes, I know its a bit dangerous...):

Function.using = Function.call; // syntactic sugar

Now you can write Object.foo.using(Objname) and it reads like a sentance.

But as a rule, stay away from altering any of the big prototypes.

链接地址: http://www.djcxy.com/p/3172.html

上一篇: JSLint突然报道:使用“使用严格”的函数格式

下一篇: Javascript中的原型对象打破了jQuery?