Заказать проект
Оставьте заявку для получения коммерческого предложения.
Заполните форму и мы вышлем Вам предложение в котором решим,
чем можем вам помочь.
Длина объекта в JavaScript

Длина объекта в JavaScript

9 Июля 2019
Николай Гоцалюк
Frontend TeamLead
Николай Гоцалюк
следующая статья

Возможно многие удивятся, но определить длину Object просто вызвав length а объекте — невозможно! Убедитесь сами:

var object = { first: 1, second: 2 };
object.length // undefined

Как бы мы не старались, ничего не получится, поскольку в Object нету параметра length. Он присутствует только у таких типов данных как array и string:

var object = { first: 1, second: 2 };
var string = 'string';
var array = [1,2,3];

object.hasOwnProperty('length'); // false
string.hasOwnProperty('length'); // true
array.hasOwnProperty('length'); // true

На пути к определению длины

В отличие от массивов, получить длину объекта всегда было сложно. Object.keys() возвращает enumerated массив всех ключей свойств объекта, а после этого можно просто использовать length и получить его длину.

var object = { first: 1, second: 2 };
Object.keys(object).length; // 2

Однако на практике не все так просто, как с первого взгляда. Поэтому для более детального объяснения было бы хорошо разобраться в происхождении этого enumerated-массива.

Как правило, когда мы хотим добавить свойство к объекту, мы можем это сделать с помощью точки:

var object = { first: 1};
object.second = 2;
console.log(object); // { first: 1, second: 2 }

Альтернативным путем может быть использовать Object.defineProperty(), который принимает три параметра: obj, prop, descriptor. Enumerated-атрибут можно указать как раз в descriptor:

const object = {};
Object.defineProperty(
 object,
 'first', {
   value: '1',
   enumerable: true 
 }
);
console.log(object); // { first: '1' }

Автоматическое опредиление

Давайте вернемся к нашему примеру свойств объекта, которые мы установили с помощью точки. Почему они отображался автоматически? Это происходит потому, что когда мы указываем свойство, атрибут enumerable автоматически устанавливается как значение true.

var object = {};
object.first = 1;
object.propertyIsEnumerable(first); // true

В большинстве случаев мы не использовали enumerable-атрибут для определения length.Это просто надежный способ контролировать, будет ли создано свойство видимым или скрытым, когда мы перебираем объект с помощью Object.keys.

Таким образом, атрибут enumerable используется для сокрытия свойств, не следует повторять. Это стало причиной введения переличуваности в ECMAScript 1.

const object = {first: '1'};
Object.defineProperty(
 object,
 'second', {
   value: '2',
   enumerable: false
 }
);
Object.keys(object); // [ 'first' ]
Object.getOwnPropertyNames(object); // [ 'first', 'second' ]

Как можно понять из примера выше, Object.getOwnPropertyNames вернет массив с именами всех ключей, в то время как Object.keys вернет массив имен только enumerableключей. Казалось бы, что лучше использовать метод Object.getOwnPropertyNames для нахождения length. Но скорее всего, эти параметры объекта не являются enumerable и должны быть скрыты. Поэтому использовать в данном контексте Object.getOwnPropertyNames — не лучшая идея.

Дополнительные возможности

Перед началом использования Object.keys по умолчанию для нахождения length объекта, необходимо сделать небольшую ремарку. В стандарте ECMAScript 6, ES6, представлен новый тип данных —  symbol. Его использование возможно в качестве имени ключа свойства объекта.

const obj = {
 [Symbol('first')]: 1,
 second: 2
};

Но при таких условиях как Object.keys так и Object.getOwnPropertyNames не будут работать так, как от них требуется.

Object.keys(obj)
// ["second"]
Object.getOwnPropertyNames(obj)
// ["second"]

Как видим, символьный ключ отсутствует в обоих массивах. Решений этой проблемы будет использование Object.getOwnPropertySymbols:

Object.getOwnPropertySymbols(obj)
// [Symbol(first)]

Таким образом мы получили массив только из имен ключей свойств типа symbol. И теперь для получения length нам необходимо просто скомбинировать оба метода:

const symbolsLength = Object.getOwnPropertySymbols(obj);
const withoutSymbolLength = Object.keys(obj);
const length = symbolsLength + withoutSymbolLength;

Need help?

Ask a question.

Chat Now
Записаться На Консультацию
Записаться На Консультацию
Мы свяжемся
с вами
в течении
10 минут
laptop
Мы свяжемся с вами в течении 10 минут