Показать сообщение отдельно
  #11 (permalink)  
Старый 28.10.2009, 18:46
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от 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
А как лучше:
Логика работы известна - выбирай
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 28.10.2009 в 18:59.
Ответить с цитированием