#javascript #arrays
#javascript #массивы
Вопрос:
Писал функцию, которая принимает массив чисел и возвращает true и индекс, если есть пропущенное число, или false, если нет пропущенных чисел. Я только что заметил кое-что о массивах, что меня смущает.
Массив, подобный
[,1,2,3,4]
выведет
[undefined,1,2,3,4]
Массив начинается с запятой, вывод имеет смысл для меня
Но почему
[1,2,3,4,] // Notice that the array ends with a comma
Печать
[1,2,3,4]
Я бы предположил, что результат будет [1,2,3,4,undefined]
.
Кто-нибудь знает, почему это так?
Ответ №1:
Конечная запятая («elision») игнорируется:
Если элемент исключен в конце массива, этот элемент не влияет на длину массива.
http://www.ecma-international.org/ecma-262/7.0/#sec-array-initializer
Обратите внимание, что справа выделена только одна запятая, так что это [1,2,,]
будет отображаться как [1,2,undefined]
.
В Javascript массивы — это просто объекты со специальным length
свойством и инициализатором массива, таким как
['a', 'b', 'c']
это ярлык для
{
"0": 'a',
"1": 'b',
"2": 'c',
"length": 3
}
Исключение заставляет инициализатор пропустить следующий индекс и увеличивает общий length
, так что это
['a', 'b', , 'c']
становится таким:
{
"0": 'a',
"1": 'b',
"3": 'c'
"length": 4
}
и два завершающих исключения
['a', 'b', 'c', , ]
стать
{
"0": 'a',
"1": 'b',
"2": 'c',
"length": 4
}
Комментарии:
1. Я не уверен, что это правда
In Javascript arrays are just objects with a special length property
. С какой точки зрения это утверждение верно? Пользовательский API?2. @Cristy: видишь ecma-international.org/ecma-262/7.0/#sec-arraycreate , пункт 6
3. Но она также «наследует» все
Array.prototype
методы, поэтому длина — не единственное отличие, как указано.4. Это так странно, но спасибо, что объяснили мне перспективу.
Ответ №2:
[,1,2,3,4]
не создает [undefined,1,2,3,4]
. Это создает [empty, 1, 2, 3, 4]
. Это разреженный массив с дырой в начале.
Из документации по конечным запятым:
JavaScript игнорирует запятые в конце в массивах. JavaScript с самого начала разрешил использовать запятые в конце в литералах массива, а позже добавил их в объектные литералы (ECMAScript 5) и совсем недавно (ECMAScript 2017) в параметры функции.
Но, если используется более одной конечной запятой, образуется дыра:
var arr = [1, 2, 3,,,];
console.log(arr.length) // 5
Ответ №3:
Массив на самом деле оказался бы [empty,1,2,3,4]
, здесь empty
по сути, дырой в памяти. Это запись, которая потеряла ссылку на память. Ссылка для подробного объяснения здесь