Какой самый быстрый способ подсчитать количество ключей / свойств объекта? Можно ли сделать это без итерации по объекту? то есть без выполнения
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox действительно предоставил волшебное свойство __count__, но оно было удалено где-то около версии 4.)
тест производительности для разных способов: jsben.ch/#/oSt2p
Возможный дубликат Длина объекта JavaScript



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не думаю, что это возможно (по крайней мере, без использования некоторых внутренних компонентов). И я не думаю, что вы выиграете от оптимизации.
Принятый ответ показывает, что это может должно быть выполнено, и у вас нет контекста, чтобы утверждать, что нет ничего, что можно было бы получить.
Если вы действительно столкнулись с проблемой производительности, я бы предложил обернуть вызовы, которые добавляют / удаляют свойства в / из объекта, с помощью функции, которая также увеличивает / уменьшает свойство с соответствующим именем (размер?).
Вам нужно всего лишь один раз рассчитать первоначальное количество объектов и двигаться дальше. Если реальной проблемы с производительностью нет, не беспокойтесь. Просто оберните этот фрагмент кода в функцию getNumberOfProperties(object) и покончите с этим.
@hitautodestruct Потому что он предлагает решение.
@crush Этот ответ, кажется, предлагает что-то сделать, а не дает прямое решение.
@hitautodestruct предлагает ответ: увеличение / уменьшение инкапсулированного счетчика с помощью методов добавления / удаления. Вот еще один ответ, похожий на этот ниже. Единственная разница в том, что Confusion не предлагал никакого кода. Ответы не являются обязательными только для кодовых решений.
@crush Верно, но не стоит начинать с вопроса. Зафиксированный :)
это может быть не идеально ... но по сравнению с другими "ответами" это может быть лучшим решением для некоторых ситуаций
Пока что это единственное решение, которое, как я вижу, представляет собой сложность производительности с постоянным временем O (1), и, следовательно, это единственное решение, которое отвечает на деталь вопроса «без повторения» и, следовательно, должно быть истинным принятым ответом. Большинство, если не все другие ответы не отвечают на этот вопрос, потому что они предлагают сложность производительности за линейное время O (n); это также относится к однострочным решениям, которые вызывают что-то вроде функции .keys (), поскольку такие вызовы функций являются O (n).
Я не знаю, как это сделать, однако, чтобы свести количество итераций к минимуму, вы можете попробовать проверить наличие __count__, и если он не существует (то есть не Firefox), вы можете перебрать объект и определите его для дальнейшего использования, например:
if (myobj.__count__ === undefined) {
myobj.__count__ = ...
}
Таким образом, любой браузер, поддерживающий __count__, будет использовать это, а итерации будут выполняться только для тех, которые этого не делают. Если счетчик изменился и вы не можете этого сделать, вы всегда можете сделать его функцией:
if (myobj.__count__ === undefined) {
myobj.__count__ = function() { return ... }
myobj.__count__.toString = function() { return this(); }
}
Таким образом, каждый раз, когда вы ссылаетесь на myobj.__count__, функция запускается и пересчитывается.
Обратите внимание, что Object.prototype.__count__ удаляется в Gecko 1.9.3: whereswalden.com/2010/04/06/…считать-property-of-objects-is-be ing-deleted /
Теперь, когда вышел Firefox 4, этот ответ устарел. Object.__count__ ушел, и скатертью дорога тоже.
Я бы не сказал, что ответ устарел. Это все еще интересная стратегия - инкапсулировать значение в функции.
должен использовать объект-прототип для расширения
Для этого в любом ES5-совместимая среда, таком как Узел, Chrome, IE 9+, Firefox 4+ или Safari 5+:
Object.keys(obj).length
Не только Node.js, но и любая среда, поддерживающая ES5.
Кстати ... просто провел несколько тестов ... этот метод работает за O (n) время. Цикл for ненамного хуже этого метода. ** грустное лицо ** stackoverflow.com/questions/7956554/…
@BMiner, это обидно, но у этого подхода есть преимущества краткости и ясности.
Это должно быть O (n), так как создается новый список размера n. то есть var o = {a: 1, b: 2}; Object.keys(o).slice(1) не влияет на o. Я до сих пор не думаю, что есть лучший ответ, чем этот!
-1 (-200, если бы я мог) Это не только выполняет итерацию по объекту, но также создает целый новый массив со всеми его ключами, поэтому он полностью не может ответить на вопрос.
Кажется, это намного быстрее, чем выполнение for (по крайней мере, в Chrome 25): jsperf.com/count-elements-in-object
@fserb Интересно! Может какая-то оптимизация? И результат FF "loop 2" - интересный выброс - в 5 раз быстрее, чем что-либо еще.
@fserb да, но только если вы его неоднократно вызываете ... в основном вы проверяете время выполнения вызова функции. добавил кешированный тест, вызывающий Object.keys только один раз. такая же скорость.
@mjs, скорее всего, ошибочная оптимизация, больше не работает быстрее на ffx 21.
@ ceram1 Вы в этом уверены? Отражает ли возвращаемое значение map.keys() изменения, внесенные в map после вызова .keys()?
@ ceram1 Java! = javascript; Кажется, вы их путаете.
@ ceram1 В этом случае людей волнует только то, как javascript является реализует метод Object.keys(), независимо от того, что является «нормальным». Указание на то, как Java что-то делает, не имеет отношения к этому разговору.
@TimTisdall Хм .. Я думаю, это может запутать новичков, поэтому удалю комментарии по поводу java. Object.keys. Согласно спецификации es5.github.io/#x15.2.3.14. Не указано, клон он или оригинал. В chrome сказано: «Поскольку результат изменчив, мы должны создавать новый клон при каждом вызове». Извините за путаницу, но можно использовать Object.keys, поскольку фиксированный массив работает очень быстро.
Этому вопросу уже несколько лет, но для тех, кто смотрит на результаты теста скорости выше, я провел тот же тест, используя lodash вместо подчеркивания: jsperf.com/count-elements-in-object/12 lodash пинает задницу подчеркивания
@JakeSellers: Я, должно быть, упустил что-то очевидное, но в чем разница между 'подчеркиванием' и 'lodash'? к тому же на моей платформе оба варианта работают примерно одинаково (оба чуть выше 18 кОпс / с).
@collapsar, я не буду вдаваться в подробности, но одному из разработчиков, который работал над подчеркиванием, не понравилось, насколько непоследовательно разрабатываются функции подчеркивания (как они работают, что они перенастраивают и т. д.), и решил создать свой собственная библиотека под названием lodash (ба-дум-тиш). Как правило, он быстрее, имеет больше функций и просто лучше (IMO). Если вы так склонны, вы можете найти обсуждения (аргументы) между двумя ведущими разработчиками на нескольких разных досках, которые позволят понять, почему произошел раскол.
Несмотря на то, что это создает совершенно новый массив, это все равно быстро. Вероятно, это связано с тем, что он реализован в собственном C или C++, поэтому, хотя он может быть не таким эффективным, поскольку C и C++ по своей сути намного быстрее, они все равно могут быть быстрее
Решена аналогичная проблема и в couchdb: "listByUniversityId": {"map": "function (doc) {\ n if (doc.type === 'ghgReport') \ n \ temit (doc.universityId, Object.keys ( doc.reports) .length); \ n} "}
Мне сложно объяснить свой вопрос, но, допустим, у меня есть прототип функции, который как бы расширяет мой объект, и я хочу только подсчитать свойства, которые имеют нормальные значения (EX: string, int)
Бесполезен для просмотра проанализированных объектов JSON.
@GetFree Почему так много пальцев вверх? Это определенно самый быстрый способ кодирования. Никаких дополнительных методов или библиотек не требуется. По скорости кода, видимо, тоже неплохо. Совсем не полный провал. 87 больших пальцев вверх не для вас.
Это выполняет итерацию по объекту. В частности, вопрос заключается в поиске решений, которые не повторяются по объекту.
@GetFree В зависимости от того, как среда JS реализует объекты, подсчет количества свойств, которые имеет объект, неизбежно может быть операцией O (n) по отношению к количеству свойств. Если это так, это будет означать, что повторение всех свойств, явно или нет, является является наиболее эффективным подходом. (Я не знаю, как среды JS реализуют объекты, поэтому это мое предположение.)
Если у вас есть список потенциальных ключей, пробовать все ключи в 10 раз быстрее. Я был очень удивлен, но тесты это подтверждают: jsperf.com/count-elements-in-object/22
Ему не нужно перебирать объект (это просто так на некоторых виртуальных машинах). Но его большой палец увеличился, потому что он работает и является решением для большинства людей, которые сталкиваются с этим вопросом от Google, ищущим быстрый способ подсчитать количество ключей. Людям, которые его поднимают, на самом деле не волнует, что происходит под капотом.
@GetFree, тогда каков оптимальный подход?
Конечно, мы заботимся о том, есть ли проблемы с тем, что находится под капотом! Оптимальный подход - использовать babel для повышения эффективности компиляции или полагаться на V8, Servo или любой другой поддерживаемый движок браузера для выполнения оптимизации. Если вы обнаружите неэффективность, сообщите об ошибке. Давайте также положим конец микропрофилированию (это нормально, если сначала он будет работать медленнее, пока он выполняет оптимизацию во время выполнения).
Когда ты контролирует объект (ваш собственный код - единственное, что добавляет к нему свойства), тогда вы можете увеличивать отдельную переменную счетчика всякий раз, когда вы добавляете новое свойство, или уменьшать при удалении свойства. Это должно быть быстрее, чем любое решение, связанное с keys (). Это не «атомарная» поточно-ориентированная операция, но для многих ситуаций это нормально. И, конечно, быстро.
Альтернатива @GetFree One O (1), о которой я могу думать, - это создать класс-оболочку Object и cont каждый раз, когда что-то добавляется или удаляется. Также вы можете написать транспилятор, который конструирует этот класс из синтаксического сахара. Дайте мне знать, если есть идеи получше. P.S. Есть много улучшений O (1), которые можно внести в текущую версию JS, включая эту и случайный выбор из объекта и т. д. Я искренне надеюсь, что эти функции будут доступны в следующей версии ES и что злоупотребление Object.keys () перестанет быть необходимым.
Вы можете использовать этот код:
if (!Object.keys) {
Object.keys = function (obj) {
var keys = [],
k;
for (k in obj) {
if (Object.prototype.hasOwnProperty.call(obj, k)) {
keys.push(k);
}
}
return keys;
};
}
Затем вы можете использовать это и в старых браузерах:
var len = Object.keys(obj).length;
Какова цель проверки (Object.prototype.hasOwnProperty.call(obj, k))?
@styfle Если вы используете цикл для для перебора свойств объекта, вы также получаете свойства в цепочке прототипов. Поэтому проверка hasOwnProperty необходима. Он возвращает только свойства, установленные для самого объекта.
Думаю, я запутался, потому что вы используете call на hasOwnProperty, а не просто используете Object.prototype.hasOwnProperty(obj, k). Какая у этого цель?
@styfle Чтобы упростить задачу, вы можете просто написать obj.hasOwnProperty(k) (я действительно сделал это в своем исходном посте, но обновил его позже). hasOwnProperty доступен для каждого объекта, поскольку он является частью прототипа Object, но в редких случаях, когда этот метод будет удален или переопределен, вы можете получить неожиданные результаты. Вызывая его из Object.prototype, он делает его немного более надежным. Причина использования call заключается в том, что вы хотите вызвать метод на obj, а не на прототипе.
Не лучше ли использовать эту версию? developer.mozilla.org/en-US/docs/JavaScript/Reference/…
@XavierDelamotte Вы абсолютно правы. Хотя моя версия работает, она очень проста и приведена в качестве примера. Код Mozilla более безопасен. (PS: ваша ссылка также есть в принятом ответе)
для новичка в js, смотрящего на этот ответ ... НИКОГДА не изменяйте классы javascript по умолчанию, никогда!
@Dmitry Этот код не изменяет класс по умолчанию. Он только добавляет прокладку для имитации стандартных функций, если она не существует.
@RenaatDeMuynck, а теперь расскажите мне, что произойдет, когда метод с именем «keys» станет стандартом в ecmaScript? И пока вы занимаетесь этим, подумайте, какие у него могут быть технические характеристики ...
@DmitryMatveev Это уже стандарт (ecma-international.org/ecma-262/5.1/#sec-15.2.3.14). Этот код добавляет стандартное поведение там, где его нет.
@RenaatDeMuynck stackoverflow.com/questions/14034180/…
@DmitryMatveev Возможно, я не проясняю свою точку зрения: не рекомендуется расширять прототипы собственных объектов Кроме при реализации отсутствующих стандартных функций (внимательно прочтите следующее: developer.mozilla.org/nl/docs/Web/JavaScript/…). Итак, как я сказал в своем предыдущем комментарии: Object.keysявляется теперь стандарт en должен будет реализован в более раннем браузере таким образом. Я бы посоветовал прочитать все внимательно еще раз, прежде чем вы снова это прокомментируете ...
Это дает тот же результат, что и: Object.getOwnPropertyNames(obj).length; намного проще.
@Wilt Вообще-то разница есть. Как указано в @ BenderTheOffender ответ, getOwnPropertyNames также считает неперечислимые свойства. Все зависит от потребностей ОП. Но поскольку он не указал, Object.getOwnPropertyNames(obj).length, вероятно, лучше.
Если вы используете Underscore.js, вы можете использовать _.размер (спасибо @douwe): _.size(obj)
В качестве альтернативы вы также можете использовать _.keys, который может быть понятнее для некоторых: _.keys(obj).length
Я очень рекомендую Underscore, это компактная библиотека для выполнения множества базовых задач. По возможности они соответствуют ECMA5 и относятся к собственной реализации.
В противном случае я поддерживаю ответ @ Avi. Я отредактировал его, чтобы добавить ссылку на документ MDC, который включает метод keys (), который вы можете добавить в браузеры, отличные от ECMA5.
Если вы используете underscore.js, вам следует использовать вместо него _.size. Хорошо то, что если вы каким-то образом переключитесь с массива на объект или наоборот, результат останется прежним.
И, насколько я понимаю, lodash обычно лучше, чем подчеркивание (хотя они делают похожие вещи).
@ MerlynMorgan-Graham, если я правильно помню, lodash изначально является вилкой подчеркивания ...
_.keys(obj).length работал лучше всего для меня, потому что мой возвращаемый объект иногда представляет собой простую строку без каких-либо свойств внутри нее. _.size(obj) возвращает мне длину строки, а _.keys(obj).length возвращает 0.
Object.keys internally. Underscore also copies every key into an array inside a for..in loop if Object.keys is not defined.
Как я решил эту проблему, так это создание моей собственной реализации базового списка, который хранит записи о том, сколько элементов хранится в объекте. Все очень просто. Что-то вроде этого:
function BasicList()
{
var items = {};
this.count = 0;
this.add = function(index, item)
{
items[index] = item;
this.count++;
}
this.remove = function (index)
{
delete items[index];
this.count--;
}
this.get = function(index)
{
if (undefined === index)
return items;
else
return items[index];
}
}
Интересная альтернатива. Это устраняет накладные расходы на функцию агрегированного подсчета, но за счет вызова функции каждый раз, когда вы добавляете или удаляете элемент, что, к сожалению, может быть хуже. Я бы лично использовал такую реализацию списка для инкапсуляции данных и пользовательских методов, которые она может предоставить по сравнению с простым массивом, но не тогда, когда мне просто нужен быстрый подсчет элементов.
Мне нравится ваш ответ, но я тоже лемминг и нажал на "положительный". Это представляет собой интересную дилемму. В своих инструкциях вы не учитываете какое-то поведение, например мою ситуацию, когда я уже проголосовал за ваш ответ, но затем я получил указание «нажать на голосование» и не могу. Инструкция не работает тихо, но из вашего контента здесь, на SO, я понимаю, что тихий сбой - это не то, что вам нравится в вашем коде. Просто предупреждаю.
Мне очень нравится этот ответ, хорошая структура данных. И если вызовы функций при добавлении оказали влияние на производительность, то при итерации по объекту было бы намного больше прироста производительности. Это должно обеспечить самый быстрый шаблон петли var i = basiclist.countwhile(i--){...}
Разве базовый список не должен включать хотя бы базовые проверки? Это похоже на проверку того, заменяет ли add старый элемент или вызывается ли remove с несуществующим индексом. Также невозможно проверить, имеет ли список данный индекс, если undefined является допустимым значением элемента.
Разве get не должен иметь if (undefined === index)? Поскольку это происходит в обратном порядке, для доступа к массиву будет использоваться индекс undefined.
Это ужасно. Если он называется списком, он должен вести себя как один. Это похоже на какой-то странный гибрид между списком и объектом, который ничего не делает. Я бы предпочел просто придерживаться основных типов данных.
@UltimateGobblement где он не ведет себя как список?
Список должен быть упорядоченным и повторяемым. Данные хранятся в объекте, поэтому нет никакой гарантии порядка элементов. Как определить длину списка с дырками? this.count? Наивысшее значение индекса? Если вы когда-нибудь добавляете два элемента по одному индексу, счетчик переходит в состояние ошибки.
@UltimateGobblement Достаточно честно. Это называется «basicList», но это еще не все. Его нужно расширять и настраивать.
При этом используется заданный символ объектов, и если есть повторяющиеся ключи, "count" не будет правильным, если не будут приняты во внимание существующие ключи.
У Google Closure для этого есть хорошая функция ... goog.object.getCount (obj)
Для тех, у кого в проекте есть Underscore.js, вы можете:
_({a:'', b:''}).size() // => 2
или функциональный стиль:
_.size({a:'', b:''}) // => 2
Для тех, у кого в проекте есть Ext JS 4, вы можете:
Ext.Object.getSize(myobj);
Преимущество этого заключается в том, что он будет работать во всех браузерах, совместимых с Ext (включая IE6-IE8), однако я считаю, что время работы не лучше, чем O (n), как и в других предлагаемых решениях.
Если указанный выше jQuery не работает, попробуйте
$(Object.Item).length
Вроде Object.Item не существует
Как заявил Avi Flax https://stackoverflow.com/a/4889658/1047014
Object.keys(obj).length
выполнит трюк для всех перечислимых свойств вашего объекта, но, чтобы также включить неперечислимые свойства, вы можете вместо этого использовать Object.getOwnPropertyNames. Вот в чем разница:
var myObject = new Object();
Object.defineProperty(myObject, "nonEnumerableProp", {
enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
enumerable: true
});
console.info(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.info(Object.keys(myObject).length); //outputs 1
console.info(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.info(myObject.hasOwnProperty("enumerableProp")); //outputs true
console.info("nonEnumerableProp" in myObject); //outputs true
console.info("enumerableProp" in myObject); //outputs true
Как указано здесь, он имеет ту же поддержку браузера, что и Object.keys.
Однако в большинстве случаев вы можете не захотеть включать неперечислимые объекты в операции такого типа, но всегда полезно знать разницу;)
Поднимите вверх за упоминание Object.getOwnPropertyNames, вы были здесь единственным ...
Стандартная реализация объекта (ES5.1 Внутренние свойства и методы объекта) не требует, чтобы Object отслеживал количество ключей / свойств, поэтому не должно быть стандартного способа определения размера Object без явного или неявного перебора его ключей.
Итак, вот наиболее часто используемые альтернативы:
Object.keys(obj).length; работает, внутри выполняет итерацию по ключам для вычисления временного массива и возвращает его длину.
Многие библиотечные примеры в другом месте в этом разделе являются полезными идиомами в контексте своей библиотеки. Однако с точки зрения производительности нет ничего лучше по сравнению с идеальным кодом без библиотеки, поскольку все эти библиотечные методы фактически инкапсулируют либо цикл for, либо ES5 Object.keys (собственный или с оболочкой).
самая медленная часть такого цикла for обычно является вызовом .hasOwnProperty() из-за накладных расходов на вызов функции. Поэтому, когда мне просто нужно количество записей объекта JSON, я просто пропускаю вызов .hasOwnProperty(), если знаю, что ни один код не сделал и не расширит Object.prototype.
В противном случае ваш код можно немного оптимизировать, сделав k локальным (var k) и используя оператор приращения префикса (++count) вместо постфикса.
var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;
Другая идея основана на кешировании метода hasOwnProperty:
var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;
Быстрее это или нет в данной среде - вопрос бенчмаркинга. В любом случае можно ожидать очень ограниченного прироста производительности.
Зачем var k in myobj повысить производительность? Насколько мне известно, только функции объявляют новую область видимости в JavaScript. Являются ли внутренние петли исключением из этого правила?
Это быстрее? for (var k in myobj) hasOwn.call(myobj, k) && ++count;, т.е. замена оператора if простым &&?
Последнее, что вы можете сделать с: Object.getOwnPropertyNames(obj).length; намного проще.
Для итерации Avi Flax ответ Object.keys (obj) .length является правильным для объекта, к которому не привязаны функции.
пример:
obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2
против
arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
_.each(obj, function(a){
arr.push(a);
});
};
Object.keys(obj).length; // should be 3 because it looks like this
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */
шаги, чтобы избежать этого:
не помещайте функции в объект, который вы хотите подсчитать, количество ключей в
используйте отдельный объект или создайте новый объект специально для функций (если вы хотите подсчитать, сколько функций находится в файле, используя Object.keys(obj).length)
также да, я использовал _ или модуль подчеркивания из nodejs в моем примере
документацию можно найти здесь http://underscorejs.org/, а также ее источник на github и другую другую информацию.
И, наконец, реализация lodash https://lodash.com/docs#size
_.size(obj)
В ответ на ваши комментарии о Array(obj).length: Не работает. http://jsfiddle.net/Jhy8M/
да, я изучил это немного больше, я собираюсь в конечном итоге удалить этот ответ, если это возможно, или просто отредактировать его все вместе
Я не вижу, чтобы это как-то связано с функциями, например, а в Chrome я вообще не вижу такого поведения. Я подозреваю, что это могло быть связано с поведением Object.defineProperty (): перечислимый по умолчанию, которым является false, хотя я еще не нашел никакой документации о том, как var obj = { a: true, b: true } может отличаться от var obj = {}; obj.a = true; obj.b = true;, или просто о том, была ли принята другая интерпретация / семантика W3 Хром.
От: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty(obj, prop, descriptor)
Вы можете добавить его ко всем своим объектам:
Object.defineProperty(Object.prototype, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
Или отдельный объект:
var myObj = {};
Object.defineProperty(myObj, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
Пример:
var myObj = {};
myObj.name = "John Doe";
myObj.email = "[email protected]";
myObj.length; //output: 2
Добавленный таким образом, он не будет отображаться в циклах for..in:
for(var i in myObj) {
console.info(i + ":" + myObj[i]);
}
Выход:
name:John Doe
email:[email protected]
Примечание: это не работает в браузерах <IE9.
Если вы собираетесь расширить встроенные прототипы или заполнить свойство (например, обезьяна-патч), сделайте это правильно: для прямой совместимости сначала проверьте, существует ли свойство, а затем сделайте свойство неперечислимым, чтобы собственные ключи построенных объектов не загрязнены. Для методов используйте действительныйметоды. Моя рекомендация: следуйте эти примеры, который демонстрирует, как добавить метод, который ведет себя как можно ближе к встроенным методам.
как указано выше: Object.keys(obj).length
Но: поскольку теперь у нас есть настоящий класс карта в ES6, я бы использовал предложить, чтобы использовать его вместо использования свойств объекта.
const map = new Map();
map.set("key", "value");
map.size; // THE fastest way
Вы можете использовать:
Object.keys(objectName).length;
и
Object.values(objectName).length;
Я стараюсь сделать его доступным для всех объектов следующим образом:
Object.defineProperty(Object.prototype, "length", {
get() {
if (!Object.keys) {
Object.keys = function (obj) {
var keys = [],k;
for (k in obj) {
if (Object.prototype.hasOwnProperty.call(obj, k)) {
keys.push(k);
}
}
return keys;
};
}
return Object.keys(this).length;
},});
console.info({"Name":"Joe","Age":26}.length) //returns 2
OP не указал, является ли объект nodeList, если это так, вы можете просто использовать метод длина для него напрямую. Пример:
buttons = document.querySelectorAll('[id=button)) {
console.info('Found ' + buttons.length + ' on the screen');
Вот несколько тестов производительности для трех методов;
https://jsperf.com/get-the-number-of-keys-in-an-object
20 735 операций в секунду
Очень просто и совместимо. Работает быстро но дорого, потому что создает новый массив ключей, который затем отбрасывается.
return Object.keys(objectToRead).length;
15 734 операций в секунду
let size=0;
for(let k in objectToRead) {
size++
}
return size;
Немного медленнее, но далеко не в области использования памяти, поэтому, вероятно, лучше, если вы заинтересованы в оптимизации для мобильных или других небольших машин.
953 839 338 операций в секунду
return mapToRead.size;
По сути, Map отслеживает свой размер, поэтому мы просто возвращаем числовое поле. Намного, намного быстрее, чем любой другой метод. Если у вас есть контроль над объектом, вместо этого преобразуйте их в карты.
Связанный: stackoverflow.com/questions/5223/…