it-swarm.com.ru

Количество элементов в объекте JavaScript

Есть ли способ получить (откуда-то) количество элементов в объекте JavaScript? (то есть сложность с постоянным временем).

Я не могу найти свойство или метод, который извлекает эту информацию. До сих пор я могу думать только о выполнении итерации всей коллекции, но это линейное время.
Странно, что нет прямого доступа к размеру объекта, не так ли?.

EDIT:
Я говорю об объекте Object (не об объектах вообще):

var obj = new Object ;
94
GetFree

Хотя реализации JS могут отслеживать такое значение внутри страны, стандартного способа его получения не существует.

В прошлом вариант Javascript в Mozilla раскрывал нестандартный __count__ , но он был удален с версией 1.8.5.

Для кросс-браузерного скриптинга вы застряли с явной итерацией по свойствам и проверкой hasOwnProperty():

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

В случае реализации с поддержкой ECMAScript 5 это также можно записать в виде (Слава Avi Flax )

function countProperties(obj) {
    return Object.keys(obj).length;
}

Имейте в виду, что вы также пропустите свойства, которые не перечисляются (например, length массива).

Если вы используете такие фреймворки, как jQuery, Prototype, Mootools, $ what-the-newest-hype, проверьте, имеют ли они собственный API коллекций, который может быть лучшим решением вашей проблемы, чем использование нативных объектов JS.

140
Christoph

Для этого в любой ES5-совместимой среде

Object.keys(obj).length

(Поддержка браузера от здесь )
(Документ на Object.keys здесь , включает метод, который вы можете добавить в браузеры не-ECMA5)

84
ZelkiN

если вы уже используете jQuery в вашей сборке, просто сделайте это:

$(yourObject).length

Это хорошо работает для меня на объектах, и у меня уже была зависимость от jQuery.

11
IndelibleHeff
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);
5
kennebec

AFAIK, нет способа сделать это надежно, если вы не переключитесь на массив. Что, честно говоря, не кажется странным - мне кажется довольно простым, что массивы исчисляются, а объекты - нет.

Вероятно, ближе всего вы получите что-то вроде этого

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

Но это создает проблемы или, по крайней мере, вопросы. Подсчитываются все созданные пользователем свойства, включая саму функцию _length! И хотя в этом простом примере вы можете избежать этого, просто используя обычную функцию, это не значит, что вы можете помешать другим сценариям делать это. так что ты делаешь? Игнорировать свойства функции?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

В конце концов, я думаю, что вам, вероятно, следует отказаться от идеи сделать ваши объекты исчисляемыми и найти другой способ сделать то, что вы делаете.

2
Peter Bailey

Понятие числа/длины/размерности на самом деле не имеет смысла для объекта, и необходимость в нем предполагает, что вы действительно хотите массив для меня.

Правка: указал мне, что вы хотите O(1) для этого. Насколько я знаю, такого пути не существует, я боюсь.

1
annakata