Функция JavaScript x () {..} рассматривается как var x = function () {..} внутри if в Firefox, а не в Chrome и Opera - PullRequest
3 голосов
/ 07 марта 2011

Рассмотрим следующий код JavaScript:

(function(){
  foo();
  function foo(){ alert('Hello, World!'); }
})();

В Firefox, Opera и Chrome это ведет себя как ожидалось;мы получаем предупреждение.В отличие от этого:

(function(){
  if (true){
    foo();
    function foo(){ alert('Hello, World!'); }
  }
})();

Firefox 3.6 и 4 (бета) (то есть SpiderMonkey для обоих) выдает исключение: foo не определено

Chrome (т.е. V8) и Opera (то есть что угоднодвижок Opera использует) работает как положено (мной).

Какое поведение правильно, или это оставлено на усмотрение реализаций?

FWIW, снова оберните его в функцию, и этохорошо снова пойти в ФФ:

(function(){
  if (true){
    (function(){
      foo();
      function foo(){ alert('Hello, World!'); }
    })();
  }
})();

Ответы [ 4 ]

2 голосов
/ 07 марта 2011

Согласно спецификации ECMA-262 5-го издания , SourceElement определяется как:

SourceElement :
Statement 
FunctionDeclaration

Итак, FunctionDeclaration с и Statement с разные. И блоки (например, if) могут содержать только Statement s:

Block :
   { StatementList opt }

StatementList :
   Statement
   StatementList  Statement

Итак, нет FunctionDeclarations через if с, грамматически, согласно спецификации. Однако, согласно FAQ по comp.lang.javascript, браузеры Mozzila и другие реализуют «оператор функции» . Это разрешено в разделе 16 ECMA-262, выпуски 3 и 5. Spidermonkey добавляет FunctionStatement. JScript добавляет FunctionDeclaration, однако JScript также имеет JScriptFunction. Похоже, что поведение остается за реализацией, чтобы решить.

Пример нестандартного FunctionStatement:

try {
  function Fze(b,a){return b.unselectable=a}
  /*...*/
} catch(e) { _DumpException(e) }

Пример FunctionExpression:

var Fze;
try {
  Fze = function(b,a){return b.unselectable=a};
  /*...*/
} catch(e) { _DumpException(e) }

Пример FunctionDeclaration:

function aa(b,a){return b.unselectable=a}
1 голос
/ 07 марта 2011

foo не анализируется до тех пор, пока не будет выполнен оператор if - И даже внутри оператора if, который вы вызываете, до его определения. Хотя, как вы сказали, он работает в Chrome и т. Д. Я ожидаю, что поведение FF проявится, если я буду писать такой код.

Я надеюсь, что для удобства обслуживания вы не пишете такой код - это запутанный беспорядок.

1 голос
/ 07 марта 2011

Это связано с разным синтаксическим анализом, который используют разные браузеры symantec.Обычно первое объявление оценивается.Так как если условие инкапсулирует объявление метода foo, оно не анализируется.В идеале не следует создавать условные методы времени выполнения.

0 голосов
/ 07 марта 2011

Чтобы быть в безопасности, напишите код так:

var foo = function () {alert ('Hello, World!'); } Foo ();

внутри блока (function () {}) () вы получите настоящие приватные методы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...