Количество элементов в объекте JavaScript
-
12-09-2019 - |
Вопрос
Есть ли способ получить (откуда-то) количество элементов в объекте JavaScript??(т.е.сложность постоянного времени).
Я не могу найти свойство или метод, который извлекает эту информацию.Пока что я могу думать только об итерации всей коллекции, но это линейное время.
Странно, что нет прямого доступа к размеру объекта, вам не кажется.
РЕДАКТИРОВАТЬ:
Я говорю о Object
объект (не объекты вообще):
var obj = new Object ;
Решение
Хотя реализации 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 это также можно записать как (Славность Ави Флакс)
function countProperties(obj) {
return Object.keys(obj).length;
}
Имейте в виду, что вы также пропустите свойства, которые не являются перечислимыми (например, length
).
Если вы используете такую структуру, как jQuery, Prototype, Mootools, $whatever-the-newest-hype, проверьте, есть ли у них собственный API коллекций, который может быть лучшим решением вашей проблемы, чем использование собственных объектов JS.
Другие советы
если вы уже используете jQuery в своей сборке, просто сделайте это:
$(yourObject).length
У меня он хорошо работает с объектами, и у меня уже был jQuery в качестве зависимости.
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);
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
В конце концов, я думаю, вам, вероятно, следует отказаться от идеи сделать ваши объекты счетными и найти другой способ делать то, что вы делаете.
Концепция числа/длины/размерности на самом деле не имеет смысла для объекта, и ее необходимость предполагает, что вам действительно нужен массив.
Редактировать:Мне указали, что для этого вам нужен O (1).Боюсь, насколько мне известно, такого способа не существует.