2013-03-30 4 views
6

Я видел много раз, что fn && fn() является оптимизацией if (fn) fn()."if (fn) fn()" или "fn && fn()"

Мой вопрос: почему? и каков сгенерированный код для обоих решений?

+2

Что вы подразумеваете под «сгенерированным кодом»? – Kobi

+0

@Kobi Я предполагаю, что он имеет в виду, что скомпилированный JavaScript компилируется - код низкого уровня. – kba

+0

@kobi, kba прав, я имею в виду код низкого уровня, ассемблер. –

ответ

13

&& оператор в JavaScript является короткозамкнутый, что означает, что если левая сторона равна false, правая часть не оценивается вообще. Вот почему fn && fn() безопасен, даже если fn является ложным (null, undefined и т. Д.).

«Сгенерированный код» будет полностью зависеть от механизма JavaScript, но я бы ожидал, что он будет очень похожим в обоих случаях (&& и if).

Это не «оптимизации» в том смысле, работает быстрее, но, скорее, в том смысле, что короче писать (особенно так, если, как я, вы не никогда оставить {} прочь if заявления). У него есть недостаток немного менее понятный для людей, которые являются новичками в этом языке, но это идиома, которую быстро узнали.

+0

Не было бы безопаснее делать 'typeof fn ===" function "'? – Antony

+0

@ Антония: Да. Вы видите эту идиому в тех местах, где код ожидает функцию или ничего (например, необязательный аргумент функции), и люди, как правило, в порядке с ним, если это терпит неудачу, если вы что-то даете, но то, что вы даете, t функция, по теории, что документация для функции (например) говорит, что вы можете предоставить функцию или ничего, но не функцию или (скажем) строку. :-) Кроме того, некоторые функции, предоставляемые хостом для некоторых движков, имеют 'typeof''" object "' (к сожалению), но по-прежнему могут быть вызваны. –

2

Итак, по if (fn) fn(), вы хотите убедиться, что перед его исполнением существует fn. условие if проверяет логическое значение или выражение, в JavaScript любое значение ложности может превратиться в значение false в условие буферизации if. Falsy значения могут быть:

  • ложные
  • нуль
  • неопределенными
  • пустая строка ''
  • номер 0
  • число NaN (да, 'не число' является номер, это специальный номер )

любое другое значение будет правдивой оценкой е.

Таким образом, если fn либо значение null или undefined, то if проверка будет защищать вас от выполнения объекта без функции.

К fn && fn(), вы делаете то же самое: в JavaScript булевское выражение проверяется, что означает, что первая часть в операции && является фальшивой, тогда вторая часть не будет выполнена. Таким образом, с помощью этой функции вы можете защитить свой код от выполнения не функционального объекта.

fn && fn() не является оптимизированной версией другой с точки зрения производительности, но является короткой версией в письменной форме.

Оба фрагмента кода требуют предусловия: функция fn может быть либо не определена, либо фактический объект функции. Если в вашем коде, fn имеет возможность быть объектом других типов, таких как строки, то вам нужно добавить проверку типа перед выполнением, например:

if (fn instanceof Function) fn()

0

С точки зрения оптимизации, IMHO, я бы сказал, потому что это лучший способ сделать его одной линией, если тогда, без необходимости жертвовать фигурными скобками и компрометировать читаемость, но это не сделало бы код более быстрым.

Смежные вопросы