Безопасно ли использовать расширенный Javascript для оператора?
Использование jQuery for-loop довольно медленное, поэтому я и рассматриваю более частое использование регулярного for-оператора. Чтобы иметь прямой доступ к текущему элементу, я нашел следующий синтаксис (для обычных массивов, а не для объектов, конечно):
for (var i = 0, e; e = array[i]; i++) { ... }
где e
в цикле представляет текущий элемент.
Безопасен ли этот синтаксис для всех браузеров?
прибавление
Хорошо, я думаю, это может сработать, но это уже не так полезно для кратких обозначений:
for (var i = 0, e; (e = array[i]) !== void(0); i++) { ... }
Спасибо всем за ответы!
3 ответа
Я не рекомендую это. Видите ли, если ваш массив выглядит следующим образом:
array = ["lala", 078, false, 992, "kas"];
Тогда ваш цикл будет проходить только первые два, так как термин e = array[i];
вернул бы false, потому что третья запись в массиве буквально ложна. Это лучше:
for (var i = 0, e; (e = array[i])===undefined; i++) { ... }
Убедитесь, что никто не перезаписывает неопределенную переменную, например, с помощью замыкания: как работает этот синтаксис JavaScript/JQuery: (функция (окно, неопределенное) { })(окно)?
Это не очень хорошая петля. Рассмотрим этот массив:
var array = [0, 1, 2, 3];
Это остановится на первом элементе, потому что 0
является фальшивым значением То же самое с
var array = ["foo", "bar", false, "hello"];
Было бы только добраться до "foo"
а также "bar"
Рассмотрите возможность использования этого цикла
for (var i=0, len=array.length; i<len; i++) { ... }
Работает везде, только рассчитывает array.length
один раз, и много исполнитель.
Согласно комментарию TJ, объем аргументов i
а также len
выше будет существовать ваша текущая функция. Так что будьте осторожны, чтобы не создавать переменные конфликты.
Несколько распространенным (но неуклюжим) способом защиты от этого является добавление префикса к переменной _
, Как это
for (var _i=0, _len=array.length; _i<_len; _i++) { ... }
Как указывает Наомик, эта форма цикла прервется, если какой-либо из элементов массива будет иметь значение Фолси. Ложные значения false
, null
, undefined
, ""
, 0
, а также NaN
, Так что это будет работать, например, для массива ненулевых ссылок на объекты. Не так много для массива строк или чисел.
Но если ваш вопрос касается синтаксиса, то да, он "безопасен" в том смысле, что он будет работать (и не работать с элементами falsey) во всех движках JavaScript. Ключевые биты, на которые вы полагаетесь:
Что доступ к элементу за пределами массива (например, в
array[array.length]
) даст вам фальшивое значение (undefined
) вместо того, чтобы бросать исключение, иЭто результат присваивания выражения (
e = array[i]
) это значение, которое было присвоено.
Да, оба из них надежны. (Ну, #1 надежен, если массив действительно является массивом JavaScript. Предоставляемые хостом объекты, похожие на массивы, могут различаться.)
В любом случае, обратите внимание, что ни i
ни e
распространяется только на цикл. ES6 будет иметь let
, который будет, но переменные объявлены с var
ограничены функцией, в которой они находятся.