2010-03-30 10 views
8

In un article su yuiblog, Douglas Crockford afferma che l'istruzione for in verrà iterata sui metodi di un oggetto. Perché il seguente codice non produce ["a", "b", "c", "d", "toString"]? Non sono .toString() e altri metodi membri di my_obj?JavaScript va per ciclo iterato sui metodi?

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"] 

risposta

12

Tutte le proprietà definite dall'utente sono enumerabili, incluse le proprietà ereditate dal prototipo. Le proprietà native incorporate non lo sono. toString() è uno di questi. Vedi qui https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Statements/For...in

Edit: La mia interpretazione di "Tuttavia, il loop iterare su tutte le proprietà definite dall'utente (comprese eventuali che sovrascrivere built-in proprietà)" è che le proprietà che vengono sovrascritti direttamente in oggetto diventa enumerabile. Non la sovrascrittura nel prototipo stesso. Ciò significa:

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

Sì, 'Object.prototype.toString.propertyIsEnumerable() == false' – CMS

+0

Dal documento si è collegato: "Un ciclo for ... in non iterare su proprietà predefinite questi. include tutti i metodi built-in di oggetti, come il metodo indexOf di String o il metodo toString di Object. Tuttavia, il ciclo eseguirà l'iterazione su tutte le proprietà definite dall'utente (incluse quelle che sovrascrivono le proprietà integrate). " Perché il documento dice che "compresi quelli che sovrascrivono le proprietà built-in" se nel mio esempio .toString() non viene sovrascritto? – hekevintran

+0

@hekevintran: aggiornata la mia risposta. –

2

for..in itera su proprietà definite dall'utente. Se si modifica il codice per:

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

Poi

console.log(a); 

uscita sarà:

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

Come Chetan Sastry ha sottolineato sottolineato, toString è trattato diversamente dal momento che è un built-in, proprietà nativa.

Problemi correlati