Почему array.indexOf(undefined) не работает, если массив разрежен

Я новичок в JavaScript, и меня беспокоит одна вещь. У меня очень простой код:

var a = [];
a[1] = 1;

i = typeof(a[0]);
index = a.indexOf(undefined);
len = a.length;

console.log(a);
console.log("\n" + len);
console.log("\n" + i);
console.log("\n" + index);

Мой вопрос: почему indexOf возвращает -1, а не 0. Я знаю, что этот метод сравнивается с ===, но я использовал его как ключевое слово параметра undefined. Если я изменю параметр метода на "undefined", он также не работает (но это для меня это очевидно). Может ли кто-нибудь объяснить мне это и сказать, что самый простой способ найти значение undefined в массиве?

Ответ 1

Это фактически найдет значение undefined в массиве, проблема в том, что ваш массив a не имеет в нем значений undefined, поэтому он возвращает -1, что означает, что он не нашел. Ваш массив выглядит так:

[*uninitialized*, 1]

Тот факт, что вы ничего не помещаете в первую позицию, не означает, что он заполнен с помощью undefined, он просто не инициализирован/не существует.

Если вы сделали что-то вроде:

var a = [undefined, 1];
var index = a.indexOf(undefined);
console.log(index);

Он действительно напечатает 0, как ожидалось.

Изменить: чтобы ответить на вопрос о том, как найти неинициализированное значение, сделайте следующее

var a = [];
a[1] = 1;

for(var i = 0; i < a.length; i++){
    if(a[i] === undefined){
      console.log(i);
    }
}

Это напечатает индекс значений неинициализированных массивов. Причина, по которой это действительно работает в отличие от indexOf, заключается в том, что a[i] будет оценивать до undefined, если:

(1) Элемент существует и имеет значение undefined или

(2) Элемент вообще не существует. indexOf однако пропустит эти "пробелы" в массиве.

Ответ 2

В общем, массивы в JavaScript являются разреженными - у них могут быть дыры в них (что почему indexOf() возвращает -1), потому что массив - это просто карта от индексов до значений. Массив, который вы ищете, называется плотным, он выглядит как

var a = Array.apply(null, Array(3)) 

или

var a = Array(undefined, undefined, undefined) 
a.indexOf(undefined) //0

Пожалуйста, посмотрите этот, я надеюсь, что это поможет вам