Array Out of Bounds: Сравнение с undefined или проверкой длины?

похоже, это обычная идиома javascript:

function foo (array, index) {
    if (typeof array[index] == 'undefined')
        alert ('out of bounds baby');
}

в отличие от более распространенных (на других языках) и концептуально более простых:

function foo (array, index) {
    if (index >= array.length)
        alert ('boo');
}

Я понимаю, что первый случай также будет работать для массивов, которые имеют "пробелы" в них, но является ли это достаточно распространенным случаем, чтобы оправдать идиому?

Пример кода, который вызвал этот вопрос, можно увидеть здесь . В этом случае при использовании переменной "аргумент" внутри функции не разумно ли считать, что это будет непрерывный массив?

Ответы

Ответ 1

Единственный правильный способ - проверить индекс по отношению к длине.

Элементу может быть присвоено значение undefined. Это просто глупо использовать его для часового здесь. (Могут быть другие, действительные и, возможно, перекрывающиеся, причины для проверки на undefined, но не "для внеочередной проверки" - код в другом вопросе будет представлять ошибочные результаты, когда значение данного аргумента действительно undefined.)

Счастливое кодирование.

Ответ 2

Вы также можете написать:

if (index in array) {

который вернет true, даже если для array[index] установлено значение undefined.

Ответ 3

Не тестируйте undefined. Вы должны использовать длину массива. Бывают случаи, когда он просто не работает для проверки на undefined, потому что undefined является законным значением для легитимной записи массива. Здесь законный массив JS:

var legalArray = [4, undefined, "foo"];

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

var legalArray = [4, undefined, "foo"];

var result = "";
for (var i = 0; i < legalArray.length; i++) {
    result += legalArray[i] + "<br>";
}

$("#result").html(result);

Создает этот вывод:

4
undefined
foo

Как видно из этого jsFiddle: http://jsfiddle.net/jfriend00/J5PPe/

Ответ 4

Это не так часто, насколько мне известно, гораздо чаще:

for (var i=0, iLen=array.length; i<iLen; i++) {
  // do stuff
}

Вам не следует сравнивать с undefined, поскольку члену массива может быть присвоено значение undefined или ему не может быть присвоено какое-либо значение.

например.

var a = [0,,,,];

alert(a.length); // 4 (or 5 in buggy IE);

a[1] === undefined; // true but not out of bounds

Основная причина использования цикла for заключается в том, что свойства массива могут не возвращаться в числовом порядке, если используется цикл for..in.

A for..in цикл намного эффективнее в разреженных массивах, но доступ к нему может быть ограничен, если это имеет значение (как должны унаследованные и нечисловые перечислимые свойства, если их следует избегать).

Ответ 5

В этом случае проверьте его, чтобы он не случайно добавил строку "undefined" в вызывающую строку. В приведенном ниже примере он фактически сделает именно это:

var undefd;
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", undefd, "ASP.NET")
// output as "ASP is dead, but {1} is alive! ASP ASP.NET"

Лично, однако, я бы, вероятно, просто кешировал длину и затем делал числовое сравнение.

ИЗМЕНИТЬ

Боковое примечание: его метод также избегает проверки NaN, но создает строгую параллель:

// this will fail unless 0001 is cast to a number, which means the method
// provided will fail. 
"{0} is dead, but {1} is alive! {0001} {2}".format("ASP", "ASP.NET")