Количество элементов в объекте JavaScript - PullRequest
93 голосов
/ 05 июня 2009

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

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

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

var obj = new Object ;

Ответы [ 6 ]

138 голосов
/ 05 июня 2009

Хотя реализации 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 .

83 голосов
/ 15 марта 2013

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

Object.keys(obj).length

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

10 голосов
/ 02 декабря 2014

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

$(yourObject).length

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

5 голосов
/ 05 июня 2009
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);
2 голосов
/ 05 июня 2009

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

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

1 голос
/ 05 июня 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...