В общем, при переходе по массиву вы хотите использовать его свойство length
в качестве решения книги. Ваше решение должно быть прекрасным в этой ситуации , в частности,, но оно имеет слабость: оно отлично подходит для записи в массиве 0
, null
, undefined
или false
, все из которых являются «ложными» значениями и поэтому document.links[i]
может быть ложным, даже если вы не были в конце массива.
Пример:
var index, a;
a = [3, 2, 1, 0, -1, -2];
for (index = 0; a[index]; ++index) {
alert(a[index]);
}
Это предупредит 3
, 2
и 1
, но затем останавливается. Сравните:
var index, a;
a = [3, 2, 1, 0, -1, -2];
for (index = 0; index < a.length; ++index) {
alert(a[index]);
}
... который предупредит 3
, 2
, 1
, 0
, -1
и -2
.
Возможно, вы увидите код, который выглядит следующим образом: for (index in a)
. В общем, не используйте это для циклических индексов массивов, это основано на неправильном понимании того, что делает for..in
. (Подробнее об этом ниже.)
(Существует новый, новый способ циклического перехода через записи массива с новой спецификации 5-го издания: функция forEach
. Вы даете ей функцию, и она вызывает ее для каждого элемент в массиве. Details in this other answer.. к сожалению, IE8 не поддерживает его, но это одна из вещей, которые могут быть «подкладками» — поиска «ES5 прокладки» для нескольких вариантов.)
при изучении массивов, важно знать, что массивы Javascript сильно отличаются от массивов на большинстве других языков.Во-первых, они не являются (обязательно) массивами; на самом деле, это обычные объекты Javascript с добавлением нескольких специальных функций. Объекты Javascript - это карты свойств, они сопоставляют ключи со значениями. Например:
var obj = {foo: 1};
Это obj
объект отображает ключ "foo"
(строка) к значению 1
. Вы можете получить доступ к этому свойству либо с использованием буквального имени в вашем коде, либо с помощью []
и строки. И, конечно, если вы делаете последнее, вы можете использовать любую строку (литерал или переменную или из выражения и т. Д.). Таким образом, все они имеют тот же результат:
x = obj.foo;
x = obj["foo"];
name = "foo";
x = obj[name];
name = "o";
x = obj["f" + name + name];
... вы получаете идею; до тех пор, пока то, что вы используете в пределах []
, оценивает строку, вы можете найти значение с помощью этого ключа. Но Javascript также делает неявное принуждение, так это работает:
var obj = {"1": "one"};
alert(obj[1]); // alerts "one"
Там я сопоставляются свойство с именем "1"
к значению "one"
. Но затем я просматриваю его с помощью obj[1]
, используя число, а не строку. Это нормально, интерпретатор превратит его в строку для меня, а затем выполнит поиск по ключевым словам.
Что все это связано с массивами? Это: Индексы массива - это просто имена собственности. Массив Javascript нормальный объект, который отображает ключи от значений, с этими особенностями:
Всякий раз, когда вы устанавливаете свойство, название которого можно интерпретировать как число, если это число больше, чем текущий максимальные указательные настоящий в массиве изменяется свойство length
. Итак:
var a = ["zero"];
alert(a.length); // alerts 1
a[3] = "three";
alert(a.length); // alerts 4, because the max index is now 3
Всякий раз, когда вы установите length
, если есть свойства с числовыми именами, которые имеют значение, большее или равное новую длину, эти свойства удаляются из объекта.
var a = ["zero", "one", "two", "three"];
alert(a[3]); // alerts "three"
a.length = 3;
alert(a[3]); // alerts "undefined", the "3" property has been deleted
// only the "0", "1", and "2" properties remain
Они имеют различные свойства функций, которые они наследуют от Array.prototype, как join
или splice
.
Всё. Ничто не похоже на массивы в C, C++, Java или большинстве других языков.
Поскольку массивы являются только объекты с несколькими дополнительными функциями, вы можете поставить другие, не-числовые свойства массивов, если вы хотите:
var a = ["zero", "one", "two"];
a.foo = "bar";
alert(a[1]); // alerts "one", 1 is implicitly coerced to "1"
alert(a["1"]); // alerts "one"
alert(a.foo); // alerts "bar"
alert(a["foo"]); // alerts "bar"
И это где for..in
вещь ломается: Потому что for..in
делает не цикл через индексы массива, он перебирает имена свойств:
var a, name;
a = [1, 2, 3];
a.foo = "bar";
for (name in a) {
alert(name);
}
Это предупреждает "1"
, "2"
, "3"
и "foo"
(в определенном порядке). Вы можете видеть, как, если бы вы предположили, что это просто индексы массивов, у вас будут проблемы!Вы можете использовать его для цикла индексов массива, но это сложнее, чем это стоит:
for (name in a) {
if (String(Number(name)) === name && a.hasOwnProperty(name)) {
alert(name);
}
}
что сначала проверяет, если имя свойства является числом, а затем проверяет, что свойство определяется на a
, а не Array.prototype (помните, что массивы наследуют свойства от прототипа Array). (Чтобы быть справедливым, эта последняя проверка, вероятно, не так уж важна, если кто-то добавляет свойства с численным именем в прототип Array, они делают очень плохое поведение (tm).)
Да, это правда. –