Кількість елементів в об'єкті javascript


103

Чи є спосіб отримати (звідкись) кількість елементів у об’єкті JavaScript ?? (тобто складність у постійному часі).

Я не можу знайти властивість або метод, який отримує цю інформацію. Поки що я можу думати лише про те, щоб зробити ітерацію через всю колекцію, але це лінійний час.
Дивно, що немає прямого доступу до розміру об'єкта, ви не думаєте.

EDIT:
Я кажу про Objectоб'єкт (а не про об'єкти взагалі):

var obj = new Object ;

5
Уже відповіли тут stackoverflow.com/questions/126100 / ... Object.keys (OBJ) .length
розмальовки

Відповіді:


155

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

У минулому варіант Javascript Jazilla піддавався нестандартності__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, які можуть бути реалізовані, це також може бути записано як (Kudos to Avi Flax )

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

Майте на увазі, що ви також пропустите властивості, які не перелічуються (наприклад, масив length).

Якщо ви використовуєте таку структуру, як jQuery, Prototype, Mootools, $ what-the-new-hype, перевірте, чи вони постачаються з власними API колекцій, що може бути кращим рішенням вашої проблеми, ніж використання нативних JS-об'єктів.


11
Проклятий я завжди забуваю hasOwnProperty. Я кажу вам занадто багато часу на землі .NET. +1
annakata

2
jQuery використовує об'єкт для своїх колекцій, який він отримує з запитів, і він виставляє це значення з властивістю довжини.
Носредна

6
Firefox4 __count__вже немає :(
Тімо Хуовінен

1
Чи є спосіб це зробити без "в"? Я в тому ж типі прив'язки, але я хотів би, щоб це пройшло JSLint, якщо це можливо.
вуличне світло

1
навіщо нам це потрібно hasOwnProperty()?
swisswiss

99

Для цього в будь-якому середовищі, сумісному з ES5

Object.keys(obj).length

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


2
Це не правильне питання, на яке можна поставити цю відповідь. З цим ви берете всі ключі об'єкта, вкладаєте їх у новостворений масив, а потім отримуєте властивість довжини з цього нового масиву.
GetFree

11
Це може бути не найбільш програмно ефективним, але є найбільш ефективним для розробників.
суперлюмінація

9

якщо ви вже використовуєте jQuery у своїй збірці, просто зробіть це:

$(yourObject).length

Це добре працює для мене на об'єктах, і я вже мав jQuery як залежний.


5
Дивно ... для мене це не працює. Я завжди отримую 1. Відповідь ЗелкіН працює на мене.
мійський гризун

3
Цей код завжди повертає 1. Всього 1 об’єкт. У ньому не
рахуються

5
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

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

Зрештою, я думаю, вам, мабуть, слід відмовитись від ідеї зробити свої об’єкти рахунковими та винайти інший спосіб робити все, що ви робите.


8
НЕБЕЗПЕЧНО БУДЕ РОБІНСОН! У НЕ прото проти об'єкта! Все походить від Object, ви будете калічити обробку клієнта так, якщо ви робите будь-яку значну кількість роботи JS.
annakata

5
Ага ... ти не читав ту частину, де я написав у коментарі "Мавпа патч з метою зробити крапку" - давай, я це робив навмисно, щоб люди не роздумували про це. Крім того, незважаючи на те, що я не виступаю за виправлення мавп, ви неправильно розумієте, як працює прототип ланцюга в Javascript, якщо ви думаєте, що це спричинить проблеми з роботою video.yahoo.com/watch/111585/1027823
Peter Bailey

Отже .. це робити чи ні?
OscarRyz

У "Javascript: хороші частини" він прототипує об'єкт методом "create ()". Я вважаю, що це визначальна книга на Javascript.
Кріс Датроу

1

Поняття числа / довжини / розмірності насправді не має сенсу для Об'єкта, і потреба в ньому говорить про те, що ви дійсно хочете масиву для мене.

Редагувати: Мені вказали, що ви хочете для цього O (1). Наскільки мені відомо, такого страху не існує.


Він запропонував ітерацію, що таке рішення. Йому потрібен був O (1) спосіб досягти цього ...
Томас Хансен

Ви абсолютно праві. Дійсно слід читати питання більш ретельно.
annakata

Насправді, Об'єкти є найближчим до Карти, яка є в JS. Карти мають довжину.
Крістіан Врабі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.