#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. 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:
length
учитываются только числовые свойства.- Массивы-это объекты, поэтому вы можете добавлять к ним другие свойства.
Вам даже не нужно использовать точечную нотацию, вы можете написать arr["dot"] = "notation";