Почему конечная запятая не добавляет undefined в массив javascript?

#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 по сути, дырой в памяти. Это запись, которая потеряла ссылку на память. Ссылка для подробного объяснения здесь

отверстия-массивы-es6