2011-01-14 6 views
33

Я работаю над этим animation function, но у меня есть проблема. Я не могу представить, что должно быть легкой задачей, я не могу получить длину объекта. Если вы посмотрите, что jsFiddle вы можете видеть, что я бегу alert(properties.length);, и он возвращает undefined. Может ли кто-нибудь понять, почему это может быть?Объект JavaScript объект буквальной длины === undefined?

+2

возможно дубликат [Длина Javascript ассоциативного массива] (http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) – ripper234

ответ

38

объект JavaScript просто сделать не имеют length свойство, только Arrays сделать. Если вы хотите узнать количество свойств, определенных на объекте, вам нужно перебирать их и подсчитывать.

Кроме того, ваш for in цикл склонен к ошибкам из-за расширения Object.prototype, так как будет проходить в полную цепочку прототипов и перечислить все свойства, которые на цепи.

Пример

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

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

Вы должны использовать метод hasOwnProperty на объекте для того, чтобы отфильтровать эти нежелательные свойства.

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

Многие фреймворков там продлить прототип, а не с помощью hasOwnProperty часто приводит к ужасным ошибкам.

Update

Об актуальной проблеме, что ваш код не анимация оба свойства.

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

В том же подсчете множество библиотек (например, jQuery) будут ужасно разваливаться, если вы расширите object.prototype, поэтому, если вы используете один из них, hasOwnProperty - это просто отходы циклов процессора. –

+0

@Martin Jespersen Итак, вы продаете код с «ПРЕДУПРЕЖДЕНИЕ, ТОЛЬКО ИСПОЛЬЗУЙТЕ С РАМКАМИ A, B И C», напечатанными на них? Извините, но использование 'hasOwnProperty' * является хорошей практикой. –

+0

Нет, я просто устал от сети, заполненной кодом javascript, который пока еще не оптимизирован, что даже хром захлопывает на нем, а затем, я думаю, я должен быть благодарен, так как я делаю свои деньги, очищая от беспорядков, которые делают: P –

0

Объекты не имеют длины, вам нужно будет использовать массив, если вы этого хотите.

Если у вас есть, чтобы найти число свойств в объекте есть только один путь:

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

Используйте hasOwnProperty, пожалуйста. –

+1

Почему, как? Где применяется hasOwnProperty? – Olical

+0

Лучше просто * не * обновить Object.prototype? Кто так делает? Это на самом деле отличный пример! –

11

Если вы используете Underscore.js, вы можете использовать _.size():

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

Я еще не видел источник, но надеюсь, что 'size()' принимает 'hasOwnProperty' во внимание. – RaphaelDDL

39

Это поддерживается в Node.js и новых средах.

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

Не поддерживается в IE8, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Browser_compatibility –

0

Вот общая функция @Junaid Кадир Shekhanzai для «найти длину объекта» (который, как мы сказали, правильно следует называть «подсчетом свойства объекта»). Он сочетает в себе решения от @Ivo Ветцель и @Martin Jespersen:

function countProperties(myObj){ 
    var length = 0; 
    if(typeof myObj != 'object'){ 
     return false; 
    } 
    for(var i in myObj) { 
    length++; 
    } 
    return length; 
} 
Смежные вопросы