Почему элемент массива JavaScript, созданный с помощью точечной нотации, существует, но не учитывается в array.length?

#javascript #arrays

Вопрос:

Хотя это противоречит здравому смыслу, можно создать массив JavaScript «свойство», используя точечную нотацию:

 const arr = [];

arr.dot = "notation";

console.log(arr.dot); // "notation"
 

Странно, но ладно. Однако длина массива по-прежнему регистрируется как 0:

 const arr = [];

arr.dot = "notation";

console.log(arr.dot); // "notation"

console.log(arr.length); // 0
 

Два вопроса:

  1. Почему на длину массива не влияет свойство, назначенное с помощью точечной записи?
  2. Почему можно назначить свойство массиву с помощью точечной записи?

Комментарии:

1. JavaScript — это странно.

2. массивы-это экзотические объекты. (грамотно)

Ответ №1:

Массив JavaScript — это просто объект. Вы устанавливаете свойство dot для объекта.

Вы можете подтвердить, что массив является объектом, выполнив:

typeof arr .

length Свойство вычисляется на основе количества числовых записей в массиве.

Вот выдержка, взятая из developer.mozilla.org:

Массивы не могут использовать строки в качестве индексов элементов (как в ассоциативном массиве), но должны использовать целые числа. Установка или доступ с помощью нецелых чисел с использованием скобочной записи (или точечной записи) не будет устанавливать или извлекать элемент из самого списка массивов, но установит или получит доступ к переменной, связанной с коллекцией свойств объекта этого массива. Свойства объекта массива и список элементов массива являются отдельными, и операции обхода и изменения массива не могут быть применены к этим именованным свойствам.

Ответ №2:

Эта точечная нотация фактически присваивает массиву свойство, а не вводит новое значение!

 const myArray = ['apples', 'bananas'];
console.log(myArray);
myArray[2] = 'peach';
console.log(myArray); 

Я предполагаю, что именно это заставило вас обратить внимание на объекты, которые делают это для назначения:

 const myObject = {
  id: 1,
  name: 'Pig',
  type: 'animal',
}

// Standard dot-notation assignment
myObject.sound = 'Oink!';
console.log(myObject);
// "Computed" assignment
myObject['emoji'] = '🐷';
console.log(myObject); 

Вот хорошее чтение по теме выше https://ui.dev/computed-property-names/.

Однако вернемся к насущному вопросу: почему я не могу этого сделать:

 const myArray = ['choclate', 'strawberry'];
myArray.pinapple = 'Tasty'; 

Массивы-это, по сути, списки. Нет смысла добавлять атрибут (т. е. «описатель») в список.

Не поймите меня неправильно — совершенно нормально задавать свойства массива (поскольку он основан на объектах JavaScript), но он используется не так, как вы думаете.

Вот пример того, когда я мог бы использовать назначение «точечная нотация» для массива:

 let zoo = ['Dolphin', 'Lion', 'Monkey'];
console.log(zoo);
// In-built property
console.log('I have', zoo.length, 'animals in my zoo!');
// Now, let's add a property "income"
zoo.income = 500;
console.log('My zoo has £%s', zoo.income);
// We can use this like a normal object property
zoo.income  = 50;
console.log('My zoo has £%s', zoo.income);
// Let's create a method for when the zoo goes out of business
zoo.closeDown = () => {
  zoo = [];
  zoo.income = 0;
  return true;
}
zoo.closeDown();
console.log(zoo);
console.log('My zoo has £%s', zoo.income); 

Почему я должен хотеть это сделать? В этом примере я мог бы использовать объект. Но возможно, что имеет больше смысла держать животных в моем зоопарке в виде массива, а затем создавать оттуда методы и свойства.

Хорошо, но как мне тогда получить список этих свойств/методов?

 const myArray = ['Foo', 'Bar'];
myArray.isCool = true;
console.log(myArray);
console.log(myArray.length);
let i;
for (i in myArray) {
  console.log(i, myArray[i]);
} 

for (i in ...) Синтаксис может быть использован здесь, поскольку мы перебираем свойства массива как объекта. Как мы уже знали ранее, массивы расширяют класс объектов (своего рода).

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for…in

Ответ №3:

  1. length учитываются только числовые свойства.
  2. Массивы-это объекты, поэтому вы можете добавлять к ним другие свойства.

Вам даже не нужно использовать точечную нотацию, вы можете написать arr["dot"] = "notation";