我可以安全地擴展Javascript builtin類,如Array
嗎?我可以安全地擴展JavaScript內置類嗎?
I.e.以下瀏覽器/環境將無法正常工作:
Array.prototype.double = function() { return this.concat(this); }
Array.twice = function(a) { return a.double(); }
Array.twice([1, 2, 3]) # => [1, 2, 3, 1, 2, 3]
我可以安全地擴展Javascript builtin類,如Array
嗎?我可以安全地擴展JavaScript內置類嗎?
I.e.以下瀏覽器/環境將無法正常工作:
Array.prototype.double = function() { return this.concat(this); }
Array.twice = function(a) { return a.double(); }
Array.twice([1, 2, 3]) # => [1, 2, 3, 1, 2, 3]
取決於您對「工作」的定義。
原型擴展有三個主要問題。
for .. in
它可以工作,Array.prototype
和Array
是可變的,所以你可以添加代碼並調用屬性。
然而:
Array.prototype.trolls = 42;
for (var k in []) {
alert(k === "trolls");
}
以上是它打破for .. in
的一個例子。這很容易用解決
Object.defineProperty(Array.prototype, "trolls", {
value: ...,
enumerable: false
});
(ES5僅。在IE <符9.不能在傳統的發動機中模擬)
或
for (var k in []) {
if ([].hasOwnProperty(k)) {
alert(k === "trolls");
}
}
我個人避免自動延伸當地人這些確切的原因。但是我認爲這是完全可以接受的有.extendNatives
函數庫中的像pd.extendNatives
+1 @Raynos我們可以隨時指望您獲得出色的JavaScript解答。 –
[Sugar.js](http://sugarjs.com/)專業。我認爲它可以在受控環境(即您自己的Web應用程序)中受益,並且如果在圖書館中正確使用它也是可以接受的。 – Tomalak
@Tomalak拓展土着不是「壞」的。我默認情況下會這樣做,最好放在'extendNatives'函數後面。如果你的庫不是原生的對象擴展庫,我認爲在庫中做這件事是不可接受的。作爲庫中的副作用擴展本地對象是不好的。擴展本地對象作爲副作用的唯一可能情況是,如果它們填充ES5規範的一部分並且100%兼容,則可以接受。 – Raynos
安全,不是真的 - 因爲你不能確定你延長他們的唯一一個,或者說你實際上延長了正確的方法(見原型 - 上次我檢查,它擴展了內建類,這對其他腳本對內建行爲的期望造成了嚴重破壞)。修改不屬於你自己的對象是一條非常棘手的領土之路(「哦,但這是實際的內置concat()
,還是其他一些腳本改變它背後?」)。
參見例如這個更詳細的討論:http://perfectionkills.com/extending-built-in-native-objects-evil-or-not/
這是一種常見的做法,我相信它會在任何地方工作。儘管我不會作爲答覆發佈,因爲其他人可能能夠確定它永遠不會導致您的問題。 –
@Michael只是補充說Object.prototype是唯一一個不受限制的。任何使用'for..in'循環數組的人都應該被絆倒。我不會添加答案,因爲我無法在所有瀏覽器上進行測試。 – Esailija
關於此主題的Andrew Dupont [給出了一個很好的JSConf演示文稿](http://blip.tv/jsconf/jsconf2011-andrew-dupont-everything-is-permitted-extending-built-ins-5211542)。 – Pointy