2010-03-30 29 views
8

在yuiblog上的article Douglas Crockford說for in語句將迭代對象的方法。爲什麼下面的代碼不會生成[「a」,「b」,「c」,「d」,「toString」]?是不是.toString()和my_obj的其他方法成員?JavaScript for in循環是否遍歷方法?

Object.prototype.toString = function(){return 'abc'} 
Object.prototype.d = 4; 

my_obj = { 
    'a':1, 
    'b':2, 
    'c':3 
} 

a = [] 
for (var key in my_obj) { 
    a.push(key) 
} 

console.log(a) // prints ["a", "b", "c", "d"] 

回答

12

所有用戶定義的屬性都是可枚舉的,包括從原型繼承的屬性。內置的本地屬性不是。 toString()就是其中之一。看到這裏https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Statements/For...in

編輯:我的解釋「然而,循環會遍歷所有用戶定義的屬性(包括任何其覆蓋內置屬性)」是那些直接在覆蓋性能對象變得可枚舉。不是原型本身的覆蓋。這意味着:

var my_obj = {a: 1, b: 2, c: 3}; 
my_obj.toString = function() {return 'abc';}; 

a = [] 
for (var key in my_obj) { 
    a.push(key) 
} 

console.log(a) // prints ["a", "b", "c", "toString"] 
+2

沒錯,'Object.prototype.toString.propertyIsEnumerable()== FALSE' – CMS 2010-03-30 01:52:29

+0

從你鏈接的文檔:「A for ... in循環不會遍歷內置屬性這些。包括所有對象的內置方法,比如String的indexOf方法或者Object的toString方法,但是循環將迭代所有用戶定義的屬性(包括覆蓋內置屬性的任何屬性)。 爲什麼文檔中說如果在我的例子.toString()中沒有覆蓋「包含覆蓋內建屬性的任何內容」? – hekevintran 2010-03-30 02:21:26

+0

@hekevintran:更新了我的答案。 – 2010-03-30 02:45:03

2

for..in遍歷用戶定義的屬性。如果你改變你的代碼:

Object.prototype.foo = function() { return 'abc'; }; 

然後

console.log(a); 

將輸出:

["a", "b", "c", "foo", "d"] 

由於Chetan Sastry尖指出,toString區別對待,因爲它是一個內置的,本地財產。