Javascript中的原型对象破坏了jQuery?

Javascript中的原型对象破坏了jQuery?,javascript,jquery,prototype,prototyping,Javascript,Jquery,Prototype,Prototyping,我在我的页面中添加了一个简单的.js文件,该文件在对象和数组原型中添加了一些相当普通的任务类函数 通过反复试验,我发现向Object.prototype添加任何函数,无论其名称或作用如何,都会导致jQuery中的Javascript错误: 罪魁祸首 Object.prototype.foo = function() { /*do nothing and break jQuery*/ }; 我在attr:function{}声明中得到的jquery-1.3.2.js第1056行的错误:

我在我的页面中添加了一个简单的
.js
文件,该文件在
对象
数组
原型中添加了一些相当普通的任务类函数

通过反复试验,我发现向
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添加函数会破坏这段代码?

我怀疑向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
}}

永远不要扩展
对象.prototype
。它不仅仅是破坏jQuery;它完全打破了Javascript的“作为哈希表的对象”特性。不要这样做


你可以问John Resig,他会告诉你答案。

我同意,在
对象中添加一些东西。原型需要谨慎,应该避免。寻找其他解决方案,例如:

将其添加到对象中,然后根据需要通过
调用
应用访问它。
例如:

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()
为了好玩,您可以添加以下内容(是的,我知道这有点危险…):

现在可以使用(Objname)
编写
Object.foo


但是作为一项规则,不要修改任何大型原型。

如果只是在循环中弄乱了…的话,你不能使用Object.defineProperty添加fn而不使其可枚举吗

因此:


似乎对我有用。这还会被认为是糟糕的形式吗

我想在我的所有对象中实现“真实”的对象定向,因此我在这个问题上绞尽脑汁,如下所示:

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冲突。

如果切换到完整的JQuery文件(非缩小),可能会出现更有意义的错误。这样您就可以更清楚地看到哪些代码有问题。@CrescentFresh的链接已过时。更新:如果我注释掉Object.prototype.foo声明,一切正常。而且,在它崩溃的时候,它甚至还没有到达我的任何代码,除了foo声明。你是对的,它没有直接破坏jQuery,它破坏了Javascript!这要看你怎么看。理想情况下,您应该能够毫无问题地扩展对象,但实际上,是的,这是一个坏主意,很少有好的理由。Crockford将枚举添加到原型中的函数视为“语言中的错误”,因此最好的做法是采取防御措施,并始终将hasOwnProperty添加到for..in循环中。这很糟糕,但我很虔诚;)是的,它破坏了jQuery,jQuery将迭代您的Object.prototype扩展,但假设它不是一个函数。当该函数出现在迭代中时,它抛出一个异常。它不会破坏JavaScript,它是JavaScript设计不可或缺的一部分@jshalvi——您可以创建一个interator函数,比如jQuery的$。each,然后只编写一次。Crockford对语言有一些误解,但这并不是他的错,他开创了西部JavaScript的野蛮前沿,在旅途中只犯了一些错误Dexting
对象。原型
很好。注意事项是在
for..in
循环中使用
hasOwnProperty
。自2.0以来,包括Safari在内的所有主流浏览器都支持它。jQuery在其
for..in
循环中没有做到这一点,这只是懒惰。性能影响是可以忽略的,Resig知道这一点:不过这只是我的观点,它比这更深。当然,您可以在类似的
循环中使用
for…解决这个问题,但是在Javascript中使用对象作为哈希表可以做很多其他事情。例如,
toString
valueOf
和其他未枚举的项。这确实有影响。此外,当你是一个被很多人使用的图书馆的首席开发人员时,你不能把他的决定归咎于懒惰。我认为最好的说法是谨慎。@JoshStodola——事实上,这不是懒惰,而是无知(大多数人不知道如何使用hasOwnProperty…),在jQuery的早期,Resig根本不知道这样做。在意识到这个缺陷后不久,他就一直接受这个补丁作为未来需要的工具,但可惜它从来没有进入核心。@CrescentFresh非常感谢你!!!我已经找那个职位好几个月了!(我是post/code diff的作者,也是与Resig合作在jQuery中修复bug的人。)我认为它永远都会消失在以太中。作为更新,我很难过地报告,几个月前,Resig正式关闭了罚单,因为它不会修复。该缺陷在UI库中太普遍,而糟糕的编码实践在社区中太普遍。这就是我不再使用jQuery的原因:(但是Sizzle与Object.prototype extensions兼容,这是我最喜欢的jQuery部分。我知道这个答案现在不正确,而且已经过时了。在ES5中,您可以使用de安全地扩展
Object.prototype
interface Object
{
    GetType: () => string;
    ToString: () => string;
    GetHashcode: () => number;
    Equals: (obj: any) => boolean;
}
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
    });