Javascript中的Prototyping对象打破了jQuery?

Ben*_*esh 35 javascript prototyping jquery prototype

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

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

罪魁祸首?

Object.prototype.foo = function() {
    /*do nothing and break jQuery*/
};
Run Code Online (Sandbox Code Playgroud)

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

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

显然G.replace是未定义的.

虽然很明显有些东西我只是没有用原型制作来解决问题,但我很难弄清楚它是什么.

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

nic*_*las 42

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

所以:

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

似乎为我工作.这还会被认为是不好的形式吗?

  • 你可以,但for..in循环被设计*来枚举原型扩展.这就是你如何探索原型链.它没有中断...在循环中它打破了错误的代码,盲目假设迭代值将始终是某种类型,而因为Object.prototype链可以包含函数,大括号之间的代码可以抛出异常时他们只期望标量和物体. (2认同)

Jos*_*ola 20

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

你可以问John Resig,他会告诉你同样的事情.

  • 扩展`Object.prototype`很好.需要注意的是在`for..in`循环中使用`hasOwnProperty`.它自2.0以来在包括Safari在内的所有主流浏览器中得到支持.只是懒惰,jQuery不会在它的`for..in`循环中做到这一点.性能影响是可以忽略的,Resig知道这一点:http://osdir.com/ml/jquery-dev/2009-02/msg00543.html但是我的意见. (20认同)
  • @Crescent比这更深刻.当然你可以使用`for ... in`循环来解决这个问题,但在Javascript中使用object-as-hashtables会做很多其他事情.例如,不会枚举`toString`,`valueOf`等.**会产生影响.此外,当你是大量人使用的图书馆的主要开发者时,你不能责怪他对懒惰的决定.我认为一个更好的词会谨慎. (3认同)
  • @JoshStodola - 实际上它不是懒惰它是无知(大多数人不知道使用hasOwnProperty ......)在早期的jQuery Resig中根本不知道这样做.在意识到这个缺陷之后不久他就一直接受这个修复作为未来需要的工具,但是它从来没有把它变成核心. (3认同)
  • 恕我直言这个答案现在不正确,已经过时了.在ES5中,您使用`Object.defineProperty`安全地扩展`Object.prototype`,并使用创建_non-enumerable_属性的默认设置. (3认同)

小智 5

我同意,添加Object.prototype要求谨慎的东西,应该避免.寻找其他解决方案,例如:

将其添加到Object,然后根据需要使用call或访问它apply.例如:

Object.foo = function () { return this.whatever()}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Function.using = Function.call; // syntactic sugar
Run Code Online (Sandbox Code Playgroud)

现在你可以写Object.foo.using(Objname),它就像一个读书.

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