Безопасно ли использовать расширенный 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. Ключевые биты, на которые вы полагаетесь:

  1. Что доступ к элементу за пределами массива (например, в array[array.length]) даст вам фальшивое значение (undefined) вместо того, чтобы бросать исключение, и

  2. Это результат присваивания выражения (e = array[i]) это значение, которое было присвоено.

Да, оба из них надежны. (Ну, #1 надежен, если массив действительно является массивом JavaScript. Предоставляемые хостом объекты, похожие на массивы, могут различаться.)


В любом случае, обратите внимание, что ни i ни e распространяется только на цикл. ES6 будет иметь let, который будет, но переменные объявлены с var ограничены функцией, в которой они находятся.

Другие вопросы по тегам