Сообщение от Octane
|
Dmitry A. Soshnikov, можешь объяснить, почему и как работает такая конструкция: typeof X // "undefined", когда переменная X нигде не определена? Нормально ли так делать?
|
Нормально, это связано с грамматикой языка.
typeof (11.4.3, ES-3) - это рекурсивное
UnaryExpression.
UnaryExpression :
[...]
typeof UnaryExpression
[...]
Т.е. можно написать так:
alert(typeof typeof []); // string
Также,
UnaryExpression в одном из нетерминалов распадается на
PostfixExpression:
UnaryExpression :
PostfixExpression
[...]
Далее, нетерминал
PostfixExpression может содержать
LeftHandSideExpression:
PostfixExpression :
LeftHandSideExpression
[...]
который, в свою очередь одним из нетерминалов имеет
CallExpression.
LeftHandSideExpression :
[...]
CallExpression
CallExpression имеет у себя
MemberExpression.
CallExpression :
MemberExpression Arguments
[...]
MemberExpression может содержать
PrimaryExpression:
MemberExpression :
PrimaryExpression
[...]
А уже
PrimaryExpression (наконец-то
) одним из своих нетерминалов имеет
Identifier:
PrimaryExpression :
[...]
Identifier
[...]
А дальше, работает обычное разрешение идентификаторов в Scope chain (10.1.4). И в этом случае будет возвращён объект типа Reference с
базой null и именем свойства - "X". Главное здесь - база null, поскольку далее отрабатывает пункт (3) алгоритма typeof:
3. If GetBase(Result(1)) is null, return "undefined".
Сообщение от Octane
|
if(typeof addEventListener != "undefined") {…}
|
Сообщение от Octane
|
if(typeof window.addEventListener != "undefined") {…}
|
В обоих случаях работает разрешение имени идентификатора. Во втором случае ищется имя "window" и дальше вызывается [[Get]] по имени свойства "addEventListener", во первом случае ищется имя "addEventListener" без дополнительных доступов к свойствам.
Сообщение от Octane
|
if(window.addEventListener) {…}
|
Просто анализируется цепь прототипов на получение значения свойства. Если свойства нет, вернётся undefined.
Сообщение от Octane
|
if("addEventListener" in window) {…}
|
Анализируется цепь прототипов на
наличие свойства. Данный случай предостерегает, если значение свойства будет
false (проверка предыдущего примера не отработала бы).
Сообщение от Octane
|
А как лучше:
|
Логика работы известна - выбирай