2011-01-14 15 views
33

Sto lavorando su questo animation function ma ho un problema. Non riesco a eseguire quello che dovrebbe essere un compito facile, non riesco a ottenere la lunghezza di un oggetto. Se controlli che jsFiddle puoi vedere che sto correndo alert(properties.length); e sta restituendo undefined. Qualcuno può capire perché questo potrebbe essere?Lunghezza letterale dell'oggetto JavaScript === undefined?

+2

possibili duplicati di [Lunghezza di Javascript Associative Array] (http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) – ripper234

risposta

38

oggetto JavaScript semplicemente fare non hanno una proprietà length, solo Arrays fanno. Se si desidera conoscere il numero di proprietà definite su un oggetto, è necessario eseguirne l'iterazione e contarle.

Inoltre, il ciclo for in è incline a bug a causa del prolungamento Object.prototype dal momento che in attraverserà la completa prototipo catena ed enumerare tutte le proprietà che sono sulla catena.

Esempio

// Poisoning Object.prototype 
Object.prototype.bar = 1; 

var foo = {moo: 2}; 
for(var i in foo) { 
    console.log(i); // logs both 'moo' AND 'bar' 
} 

Devi utilizzare il metodo hasOwnProperty sull'oggetto al fine di filtrare tali proprietà indesiderati.

// still the foo from above 
for(var i in foo) { 
    if (foo.hasOwnProperty(i)) { 
     console.log(i); // only logs 'moo' 
    } 
} 

Molti framework JavaScript là fuori estendere il prototipo, non usando hasOwnProperty spesso porta ad errori orribili.

Aggiornamento

Per quanto riguarda il problema reale che il codice non è l'animazione entrambe le proprietà.

for(var p in properties) { 
    ... 
    for(var i = 0; i <= frames; i++) 
    { 
     setTimeout((function(exti, element) { 
      return function() { 

       // p gets overriden by for outer for in loop 
       element.style[p] = original + (pixels * exti) + 'px'; 
      } 

     // you need to pass in a copy of the value of p here 
     // just like you do with i and element 
     })(i, element), i * (1000/60), element); 
    } 
    .... 
} 
+0

Sullo stesso numero un sacco di librerie là fuori (come jQuery) andranno in pezzi in modo orribile se si estrae object.prototype, quindi se si usa uno di loro hasOwnProperty è solo uno spreco di cicli cpu. –

+0

@Martin Jespersen Quindi vendi il codice con "ATTENZIONE USARE SOLO CON I FRAMEWORKS A, B AND C" stampati su di essi? Siamo spiacenti, ma l'uso di 'hasOwnProperty' * è ** una buona pratica. –

+0

No, sono solo stanco di un web pieno di codice javascript che è così lontano dall'ottimizzazione che anche il cromo soffoca su di esso, quindi di nuovo, credo dovrei essere grato da quando faccio i miei soldi ripulendo il casino che gli altri fanno: P –

0

Gli oggetti non hanno lunghezza, è necessario utilizzare un array se lo si desidera.

Se dovete trovare il numero di proprietà in un oggetto non v'è un solo modo:

var length =0; 
for(var i in obj) length++; 
+9

Utilizzare hasOwnProperty, per favore. –

+1

Perché, come? Dove si applica hasOwnProperty a questo? – Olical

+0

Meglio solo * non * aggiornare Object.prototype? Chi lo fa? Questo è davvero un grande esempio! –

11

Se si utilizza Underscore.js, è possibile utilizzare _.size():

_.size({one : 1, two : 2, three : 3}); 
=> 3 
+0

Devo ancora vedere la fonte ma spero che 'size()' tenga conto di 'hasOwnProperty'. – RaphaelDDL

39

Questo è supportato in node.js e ambienti nuovi.

var obj = {a: "a", b: "b"}; 
Object.keys(obj).length // 2 
+0

Non supportato in IE8, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Browser_compatibility –

0

Ecco la funzione generale di @Junaid Qadir Shekhanzai per "trovare la lunghezza di un oggetto" (che, come c'è stato detto, dovrebbe essere propriamente chiamata "contare le proprietà di un oggetto"). Esso combina soluzioni di @ Ivo Wetzel e @ Martin Jespersen:

function countProperties(myObj){ 
    var length = 0; 
    if(typeof myObj != 'object'){ 
     return false; 
    } 
    for(var i in myObj) { 
    length++; 
    } 
    return length; 
} 
Problemi correlati