Prototyping Object in Javascript breaks jQuery?

ぃ、小莉子 提交于 2019-11-26 13:21:33
Josh Stodola

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?

davehamptonusa

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.

I banged my head around this problem as I wished to implement "real" object orientation in all of my objects, like this:

interface Object
{
    GetType: () => string;
    ToString: () => string;
    GetHashcode: () => number;
    Equals: (obj: any) => boolean;
}

Since Object.prototype breaks JQuery, I defaulted to the abovementioned solution to make use of defineProperty but that does not take any arguments.

The good news is that you can hack into defineProperty and actually accept parameters. Here is my implementation:

Object.defineProperty(Object.prototype, "Equals",
    {
        value: function (obj: any)
        {
            return obj == null && this == null
                    ? true
                    : obj != null && this == null
                        ? false
                        : obj == null && this != null
                            ? false
                            : this.GetHashcode() == obj.GetHashcode();
        },
        enumerable: false
    });

This works and does not clash with JQuery.

I doubt adding a function to Object.prototype breaks jQuery directly. Just make sure each for..in loop you have throughout your site is wrapped in a hasOwnProperty check, since you've add the function globally and the result of iterating over it can be unpredictable:

Object.prototype.foo = function() {};    
var myObject = {m1: "one", m2: "two" };

for(var i in myObject) { if(myObject.hasOwnProperty(i)) {
   // Do stuff... but not to Object.prototype.foo
}}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!