2013-03-25 76 views
7
Object.prototype.doSomething = function(p) { 
    this.innerHTML = "<em>bar</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

document.getElementById("foo").doSomething("Hello World"); 

<div id="foo"><strong>foo</strong></div>可以在Javascript中定義Object中的原型函數嗎?

上面的代碼工作正常。

但我記得我看到這個地方:Do not mess with native Object.好,就像那樣。

那麼可以定義一個原型函數對象?有什麼理由不應該這樣做嗎?

+0

這是一個圖書館其他人將被消耗?或者爲你自己的應用程序代碼? – 2013-03-25 17:07:16

+0

我在寫一個其他人可能也在使用的小型圖書館。正如下面提出的答案,我認爲我不應該這樣做,不管是誰編寫的代碼。 – user1643156 2013-03-25 17:17:04

回答

5

比較安全的方法添加到Object.prototype是使用ES5方法Object.defineProperty創建不可枚舉屬性:

Object.defineProperty(Object.prototype, 'doSomething', { 
    value: function(p) { ... }, 
    enumerable: false, // actually the default 
}); 

這將確保,如果你做for (key in object)新的屬性不會出現。

請注意,由於ECMAScript/JavaScript以前版本中不存在不可枚舉的屬性,因此無法可靠地對此函數進行擦除。

無論如何,如果您的方法僅適用於HTML頁面元素,那麼最好將其添加到Element.prototype而不是Object.prototype,儘管如果您這樣做,較老的(IE)瀏覽器可能會發生抱怨。

+0

雖然現在不是['hasOwnProperty'](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)是最佳做法嗎? – 2013-03-25 17:06:28

+0

@RoatinMarth不,恕我直言'hasOwnProperty'是_old_最佳做法。在ES5瀏覽器中,應該沒有必要。任何與Object.prototype不清的代碼應該被放逐。即使jQuery忽略'hasOwnProperty'測試,並明確指出,如果使用濫用它的代碼,它會失敗。 – Alnitak 2013-03-25 17:07:49

+0

'在以前版本的Javascript中不存在不可枚舉的屬性。''您用'previous'指代哪個版本? – user1643156 2013-03-25 17:21:14

1

一般不是個好主意。該功能現在可在上使用對象原型(這是很多)的應用程序中的所有內容,並將顯示在枚舉Object proto的函數中。

一個更好的選擇是定義一個單獨的原型:

function MyObject { 
    ... 
} 

MyObject.prototype.doSomething = function() { 
    ... 
} 

var myObj = new MyObject(); 
1

如果添加的東西到對象原型,你失去了使用for p in obj漂亮的對象迭代功能,因爲枚舉的屬性已添加的迭代,如以及所有物體上的

例如:

Object.prototype.doSomething = function(p) { 
    this.innerHTML = "<em>bar</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

for (p in {foo:"bar"}){ 
    console.log(p); 
} 

//foo 
//doSomething 

沒想到,你也將獲得doSomething記錄。爲了解決這個問題,當迭代你的對象時你必須添加一個hasOwnproperty檢查,但是這裏的風險在於你可能會打破其他代碼,而這些代碼並不期望一個普通對象具有文本中指定的其他屬性。

+0

自_enumerable_屬性已添加... – Alnitak 2013-03-25 17:00:25

+0

@Alnitak更新,謝謝。 – 2013-03-25 17:02:29

0

另一種選擇是呼叫的方法,而不是定義爲對象的原型方法 -

function doSomething(p) { 
    this.innerHTML = "<em>"+p+"</em>"; 
    this.style.color = "#f00"; 
    alert(p); 
}; 

//

doSomething.call(document.getElementById("foo"),"Hello World"); 
相關問題