2011-09-22 75 views
2
var x = { 
    article: "bla bla bla ", 
    journal: "le monde ", 
    magazine: "playboy" 
}; 

for (var i in x) { 
    alert(i + " "+ x[i]); 
} 

每個JS對象都有一個valueOftoString方法。當我遍歷x對象的屬性時爲什麼看不到它們?迭代javascript對象和valueOf toString方法

+0

無法看到究竟是什麼? –

+0

是的,它在FF中正常工作。可能是瀏覽器特定的問題。 – RHT

回答

0

發動機具體隱藏這些從枚舉方法。

這樣做的目的是允許遍歷對象屬性,而無需由對象的原型的屬性的困擾。通過這種方式,您可以遍歷數組下標,將對象用作散列表並遍歷其屬性。

這可以然而,可以容易破碎。例如,如果你使用Object.property一個自定義的方法,它會突然所有對象的屬性的枚舉過程中出現:

var obj = { foo: 0 }; 

Object.prototype.bar = 1; 

// prints 'foo' and 'bar' 
for (var k in obj) { 
    console.log(k); 
} 

這使得它的危險,延長Object.prototype中。

您可以測試是否一個屬性來自於物體本身,或者通過使用Object.hasOwnProperty方法的原型:

// prints 'foo' 
for (var k in obj) { 
    if (!obj.hasOwnProperty(a)) continue; 
    console.log(k); 
} 

或者,你可以使用Object.defineProperty就定義非枚舉的屬性,如果你不在乎舊瀏覽器:

Object.defineProperty(Object.prototype, 'bar', {value: 1, enumerable: false}); 

// prints 'foo' 
for (var k in obj) { 
    console.log(k); 
} 
+0

它爲什麼這麼做不一致?爲什麼對象原型方法隱藏枚舉,但數組原型方法不是? –

+0

陣列原型應該隱藏起來。只有以這種方式定義它們的庫纔不會。 –

+0

@PeterOlson我相信陣列的默認原型屬性不會出現在枚舉。例如,「長度」不是。正如@ NotAName所說,你看到的屬性很可能來自你使用的庫。 – arnaud576875

0

它們不是可枚舉的屬性。嘗試Object.getOwnPropertyNames。只適用於某些瀏覽器:

這並不檢查原始的,所以你需要做的事情很複雜:

var x, y, z, getAllKeys; 
getAllKeys = function (obj,ar) { 
    ar = ar || [new Array]; 
    ar[0] = ar[0].concat(Object.getOwnPropertyNames(obj)); 
    if (obj !== Function.prototype && Object.getPrototypeOf(obj)) { 
     getAllKeys(Object.getPrototypeOf(obj),ar); 
    } 
    return ar[0]; 
} 
console.log (getAllKeys(new Array)); 
for (x in y = getAllKeys(z = new Array)) { 
    var key = y[x]; 
    var value = z[y[x]]; 
} 

責備的JavaScript是荒謬的,看起來像組裝,也許jASM將是一個更好的名字嗎? (玩笑)

+0

您是否知道'對象.__ proto__'指'Function.prototype',而不是到'null'價值?如果您使用的是Object.getOwnPropertyNames,那麼爲什麼不使用Object.getPrototypeOf而不是使用非標準的和不推薦使用的__proto__? – CMS

+0

它永遠不會被刪除在這個速度。但也有可能一些瀏覽器具有Object.getOwnPropertyNames,但不包含Object.getPrototypeOf。無性也只是隨機的。否則我可能會輸入null。 :P –

+0

繼續前進並修復它。 –