Длина литерала объекта JavaScript === не определена?

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


person Olical    schedule 14.01.2011    source источник
comment
возможный дубликат Длина ассоциативного массива Javascript   -  person ripper234    schedule 31.01.2012


Ответы (5)


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

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

Пример

// 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'
    }
}

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

Обновить

Что касается фактической проблемы, что ваш код не является анимацией, оба свойства.

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);
    }
    ....
 }
person Ivo Wetzel    schedule 14.01.2011
comment
В то же время многие библиотеки (например, jQuery) ужасно развалятся, если вы расширите object.prototype, поэтому, если вы используете одну из них hasOwnProperty, это просто пустая трата циклов процессора. - person Martin Jespersen; 14.01.2011
comment
@Martin Jespersen Итак, вы продаете код с напечатанным на нем ПРЕДУПРЕЖДЕНИЕМ ИСПОЛЬЗОВАТЬ ТОЛЬКО С ФРЕЙМАМИ A, B И C? Извините, но использование hasOwnProperty является* хорошей практикой. - person Ivo Wetzel; 14.01.2011
comment
нет, я просто устал от сети, заполненной кодом javascript, который настолько далек от оптимизации, что даже хром задыхается от него, с другой стороны, я думаю, я должен быть благодарен, так как я зарабатываю свои деньги, убирая беспорядок, который делают другие: P - person Martin Jespersen; 14.01.2011
comment
Я действительно не понимаю, к чему вы клоните со всей этой штукой hasOwnProperty. Я не знал, что устанавливаю прототип? - person Olical; 14.01.2011
comment
@Martin Тогда никогда больше не используйте jQuery, он заполнен вызовами hasOwnProperty. То, что вы делаете, это преждевременная оптимизация, ничего больше. - person Ivo Wetzel; 14.01.2011
comment
@Wolfy Я просто хотел указать на возможную ошибку, которая может произойти, когда другой код (будь то ваш, который вы напишете через 2 недели) или другой скрипт, который вы можете использовать на своей странице, расширяет прототип, так как тогда в вашем properties объект. - person Ivo Wetzel; 14.01.2011
comment
@Ivo Wetzel О, да, я думал, что это проблема с моим текущим кодом. И я подумал, что мой скрипт не работает из-за отсутствия длины и из-за этого не работает оператор for in. Итак, теперь я знаю, что с объектом все в порядке. Знаете ли вы, почему он анимирует только высоту, а не и то, и другое? - person Olical; 14.01.2011
comment
@Ivo легко ... ваш пример хорош, и вы правы, у него есть и подтяжки, и ремень, в этом нет ничего плохого, я просто предлагал более простую и быструю альтернативу - не принимайте на свой счет, что у нас разные мнения;) - person Martin Jespersen; 14.01.2011
comment
@Wofly Вам также нужно передать p в оболочку анимации, точно так же, как i и element, поскольку в противном случае for in loop переопределит p. - person Ivo Wetzel; 14.01.2011
comment
@Иво Конечно! Потому что у меня есть функции внутри функций. Спасибо тебе за это! - person Olical; 14.01.2011
comment
Массивоподобные объекты тоже имеют свойство длины :))) Но они не массивы. - person Alexandr; 14.01.2011
comment
@Alexandr Действительно, но здесь пытались избежать еще большей путаницы, следует также отметить, что единственный реальный объект JS, который ведет себя как массив, - это аргументы. Остальное является частью DOM :) - person Ivo Wetzel; 14.01.2011
comment
@Ivo Wetzel Конечно, твой ответ - превосходен! И этого совершенно достаточно, чтобы понять причину проблемы. - person Alexandr; 14.01.2011

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

var obj = {a: "a", b: "b"};
Object.keys(obj).length // 2
person Jamund Ferguson    schedule 06.03.2012
comment
Не поддерживается в IE8, developer.mozilla .org/en-US/docs/Web/JavaScript/Reference/ - person Igor Parra; 23.02.2015

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

_.size({one : 1, two : 2, three : 3});
=> 3
person Casey    schedule 06.03.2012
comment
Мне еще предстоит увидеть источник, но я надеюсь, что size() учитывает hasOwnProperty. - person RaphaelDDL; 10.04.2014

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

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

var length =0;
for(var i in obj) length++;
person Martin Jespersen    schedule 14.01.2011
comment
Используйте hasOwnProperty, пожалуйста. - person Ivo Wetzel; 14.01.2011
comment
Почему как? Где к этому относится hasOwnProperty? - person Olical; 14.01.2011
comment
Лучше просто не обновлять Object.prototype? Кто так делает? На самом деле это отличный пример! - person Jamund Ferguson; 06.03.2012
comment
@IvoWetzel был бы признателен за пример. Я использовал ответ Мартина Йесперсена здесь jsfiddle.net/jeykeu/qAH48 Это правильный путь? ? - person Junaid Qadir Shekhanzai; 13.03.2012

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

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