Javascript中的原型对象打破了jQuery?
我已经添加了一个简单的.js
文件到我的页面,有一些漂亮的普通任务types的function添加到Object
和Array
原型。
通过试验和错误,我已经find了将任何函数添加到Object.prototype
,不pipe它的名称或它是什么导致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(/-([az])/ig, function(all, letter) { return letter.toUpperCase(); });
显然G.replace是未定义的。
虽然很明显,我只是没有用原型来包装我的东西,但是我很难弄清楚它是什么。
要清楚,我不是在寻找解决方法,我已经处理了…我在寻找的是对为什么的答案? 。 为什么向Object.prototype
添加一个函数会破坏这段代码?
你永远不应该扩展Object.prototype
。 它远不止于jQuery; 它完全打破了Javascript的“对象 – 哈希表”function。 不要这样做。
你可以问John Resig,他会告诉你同样的事情 。
如果它只是一个混乱的情况下…在循环中,你不能使用Object.defineProperty来添加你的FN,而不是让它枚举?
所以:
Object.defineProperty(Object.prototype, "foo", { value: function() { // do stuff }, enumerable : false });
似乎为我工作。 这仍然被认为是不好的forms?
我同意,添加一些Object.prototype
需要谨慎,应该避免。 寻找其他解决scheme,如:
将其添加到Object,然后根据需要使用call
或apply
访问它。 例如:
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)
,它读起来就像一个感觉。
但作为一个规则,远离改变任何大型原型。
我在这个问题上敲了敲头,因为我希望在所有的对象中实现“真正的”对象定位,例如:
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冲突。
我怀疑添加一个函数来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 }}