2011-01-14 13 views
33

Ich arbeite an diesem animation function, aber ich habe ein Problem. Ich kann nicht scheinen, was eine leichte Aufgabe sein soll, ich kann die Länge eines Gegenstandes nicht bekommen. Wenn Sie dieses jsFiddle auschecken, können Sie sehen, dass ich alert(properties.length); ausgeführt habe und es undefined zurückgibt. Kann jemand sehen, warum das sein könnte?JavaScript-Objekt Literallänge === undefiniert?

+2

möglich Duplikat [Länge von Javascript assoziatives Array] (http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) – ripper234

Antwort

38

JavaScript-Objekt einfach tun nicht haben eine length Eigenschaft, nur Arrays tun. Wenn Sie wissen möchten, wie viele Eigenschaften für ein Objekt definiert sind, müssen Sie über sie iterieren und sie zählen.

Auch Ihre for in Schleife ist anfällig für Fehler aufgrund Verlängerung der Object.prototype da die komplette Prototypkette und aufzählen alle die Eigenschaften durchqueren, die an der Kette sind.

Beispiel

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

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

Sie haben die hasOwnProperty Methode für das Objekt zu verwenden, um die unerwünschten Eigenschaften zu filtern.

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

Viele JavaScript-Frameworks gibt den Prototyp verlängern, nicht mit hasOwnProperty führt oft zu schrecklichen Fehler.

aktualisieren

In Bezug auf das eigentliche Problem, dass Ihr Code nicht beide Eigenschaften ist Animation.

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

Auf der gleichen Anzahl werden viele Bibliotheken da draußen (wie jQuery) schrecklich auseinander fallen, wenn Sie object.prototype erweitern, also wenn Sie eine von ihnen verwenden, ist hasOwnProperty nur eine Verschwendung von CPU-Zyklen. –

+0

@Martin Jespersen Sie verkaufen also den Code mit "WARNING DO NUR MIT FRAMEWORKS A, B UND C verwenden" auf ihnen gedruckt? Tut mir leid, aber 'hasOwnProperty' * ist ** eine gute Übung. –

+0

nein, ich bin nur müde von einem Web mit JavaScript-Code gefüllt, der so weit davon entfernt ist, dass Chrom chokes darauf optimiert ist, dann wieder, ich denke, ich sollte dankbar sein, da ich mein Geld räumen das Durcheinander machen andere machen: P –

0

Objekte haben keine Länge, Sie müssen ein Array verwenden, wenn Sie das möchten.

Wenn Sie die Anzahl der Eigenschaften in einem Objekt zu finden, haben es nur einen Weg:

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

Verwenden Sie bitte hasOwnProperty. –

+1

Warum, wie? Wo gilt hasOwnProperty? – Olical

+0

Besser, * Object.prototype * nicht * nur zu aktualisieren? Wer macht das? Das ist eigentlich ein großartiges Beispiel! –

11

Wenn Sie Underscore.js verwenden, können Sie _.size() verwenden:

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

Ich habe noch die Quelle zu sehen, aber ich hoffe, dass 'size() '' hasOwnProperty' berücksichtigt. – RaphaelDDL

39

Dies ist in node.js und neueren Umgebungen unterstützt.

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

Nicht unterstützt in IE8, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Browser_compatibility –

0

Hier @Junaid Qadir allgemeine Funktion des Shekhanzai für „die Länge eines Objektes zu finden“ (die als uns gesagt, richtig genannt „die Eigenschaften eines Objekts zu zählen“ werden sollte). Es vereint Lösungen von @ Ivo Wetzel und @ Martin Jespersen:

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