2013-01-23 58 views
1

我知道你should avoid it,因此雖然煩人,我總是保護自己免受它。什麼原因變量在使用「for in」時顯示?

但是究竟是什麼原因導致原型的擴展在使用「for in」時出現?有時候(或似乎是)可以安全地使用「for in」,而其他時間則不可以。

即:

我談論例如:

Array.prototype.last = function(){ return this[this.length-1]; } 

顯示爲:

for(var k in someArray){ 
    console.log("%o %o", k, someArray[k]); // eventually outputs "last 'function(){ return this[this.length-1]; }' 
} 
+0

你有一個流浪'''那裏,我不知道它應該去哪裏... – Neal

+1

是什麼原因導致它?沒有真正的......它發生,因爲[規範sa ys so](http://es5.github.com/#x12.6.4)(「枚舉對象的屬性包括枚舉其原型的屬性...」) –

+0

你是什麼意思,你「保護」自己反對它?你的意思是'hasOwnProperty'?如果是這樣,那仍然是迭代數組的錯誤方法。只要你正確地循環,在你自己的代碼中擴展'Array.prototype'沒什麼問題。 –

回答

4

此行爲是由設計。

for in遍歷所有可枚舉的屬性,包括那些從原型繼承的屬性。

+1

+1也許你應該提到一些關於'hasOwnProperty'如何用來避免「繼承」的屬性,如果需要'for ... in'循環的話。 – jbabey

3

正如SLaks說的那樣,它是有設計的。什麼決定一個屬性(繼承與否)是否會在for..in循環中顯示它的[[Enumerable]]內部屬性。如果這是真的,財產將顯示,否則它不會。

每個屬性都有這樣一個屬性(和其他一些屬性)。可以使用Object.getOwnPropertyDescriptor進行檢查。例如,考慮您的Array.prototype.last方法:

var descriptor = Object.getOwnPropertyDescriptor(Array.prototype, "last"); 

它會返回一個對象是這樣的:

{ 
configurable: true, 
enumerable: true, 
value: function(){ return this[this.length-1]; }, 
writable: true 
} 

您可以更改的值[可枚舉]與Object.definePropertyfor..in循環隱藏它:

descriptor.enumerable = false; 
Object.defineProperty(Array.prototype, "last", descriptor); 
相關問題