Javascript中的Prototyping对象打破了jQuery?

时间:2009-12-01 16:49:37

标签: javascript jquery prototype prototyping

我在页面中添加了一个简单的.js文件,其中添加了一些非常普通的常见任务类型的函数添加到ObjectArray原型中。

通过反复试验,我发现将任何函数添加到Object.prototype,无论它的名称或它的作用是什么导致jQuery中的Javascript错误:

罪魁祸首?

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

错误我在attr:function {}声明中获得了jquery-1.3.2.js的第1056行:

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

显然G.replace未定义。

虽然很明显有一些事情我只是没有用原型设计来解决问题,但我很难弄清楚它是什么。

要说清楚,我不是在寻找一种解决方法,我已经处理好了......我正在寻找的是为什么?的答案。为什么向Object.prototype添加一个函数会破坏这段代码?

5 个答案:

答案 0 :(得分:41)

如果它只是一个搞乱......循环的情况,你不能使用Object.defineProperty添加你的fn而不使它可枚举吗?

所以:

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

似乎适合我。这还会被认为是不好的形式吗?

答案 1 :(得分:20)

你永远不应该延长Object.prototype。它不仅仅是打破jQuery;它彻底打破了Javascript的“object-as-hashtables”功能。不要这样做。

你可以问John Resig,他会告诉你same thing

答案 2 :(得分:5)

我同意,在Object.prototype添加一些内容需要谨慎,应该避免。寻找其他解决方案,例如:

将其添加到Object,然后根据需要使用callapply访问它。 例如:

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

然后通过以下方式在对象上调用它:

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

为了好玩,你可以添加以下内容(是的,我知道它有点危险......):

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

现在你可以写Object.foo.using(Objname),它看起来像是一个遗产。

但作为一项规则,远离改变任何大型原型。

答案 3 :(得分:1)

我想解决这个问题,因为我希望实施"真正的"我所有对象中的面向对象,如下所示:

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

由于Object.prototype打破了JQuery,我默认使用了上面提到的解决方案来使用defineProperty,但是没有任何参数。

好消息是你可以入侵defineProperty并实际接受参数。这是我的实施:

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
    });

这有效,并且不与JQuery冲突。

答案 4 :(得分:-1)

我怀疑向Object.prototype添加一个函数会直接破坏jQuery。只需确保整个站点中的每个for..in循环都包含在hasOwnProperty检查中,因为您已经全局添加了该函数,并且迭代它的结果可能是不可预测的:

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
}}