Подтвердить что ты не робот

Какой синтаксис JS-функции-объявления соответствует стандарту?

  var foo = function(){ return 1; };
  if (true) {
    function foo(){ return 2; }
  }
  foo(); // 1 in Chrome // 2 in FF
  //I just want to be sure, is FF 4 not "standard" in this case?

Edit:

что, если у нас есть это:

  var foo = function(){ return 1; };
  if (true) function foo(){ return 2; }      
  foo(); // is 1 standard or is 2 standard?
4b9b3361

Ответ 1

Исходный код плаката не разрешен стандартом ECMAScript. (ECMAScript - официальное название спецификации языка JavaScript по юридическим причинам.) Это, однако, общее расширение языка: один, который, к сожалению, реализован по-разному в разных браузерах.

В стандартном JavaScript определения функций могут возникать только в коде верхнего уровня или на верхнем уровне тела функции. Вы не можете иметь условные обозначения, циклы или даже фигурные скобки между корпусом закрывающей функции и определением функции.

Например, это разрешено:

  function f() {
    function g() {
      ...
    }
  }

но это не так:

  function f() {
    {
      function g() {
        ...
      }
    }
  }

Что усложняет изображение, так это то, что большинство браузеров действительно принимают этот последний код, но каждый присваивает ему свою индивидуальную интерпретацию. Firefox относится к нему так:

  function f() {
    {
      var g = function g() {
        ...
      }
    }
  }

Комитет ECMAScript рассматривает возможность выбора конкретной интерпретации для этих "операторов функций" (в отличие от определений функций). Они еще не приняли решение. Mozilla обсуждает свое предпочтительное решение здесь.

Ответ 2

Код в вопросе фактически не разрешен текущим синтаксисом ECMAScript (как из ECMAScript 5). Вы можете сделать var foo = function() {} внутри блока, но вы можете сделать только function foo() {} на уровне или в функциях или скриптах.

В настоящее время браузеры поддерживают код в вопросе несовместимыми способами, потому что все они реализуют расширения для основного языка и реализуют разные расширения. Полностью соответствующая реализация ECMAScript 5 на самом деле заканчивается SyntaxError при компиляции этого script.

Есть предложения добавить возможность делать подобные вещи в ECMAScript, но они еще не совсем финализированы.

Ответ 3

Оба являются технически неправильными, в соответствии со стандартом ECMAScript, поскольку объявления функций разрешены только на верхнем уровне или непосредственно внутри других функций. Технически объявление функции внутри блока if является синтаксической ошибкой. Большинство реализаций позволяют это как в расширении, но они интерпретируют его по-разному.

Причина разницы в том, что Chrome обрабатывает объявление foo как объявление нормальной функции и поднимает его до начала области. Firefox (по историческим причинам IIRC) объявляет только функцию, когда выполняется оператор if.

Чтобы лучше продемонстрировать разницу, вы можете попробовать запустить этот похожий код:

console.log(foo()); // 2 in Chrome, error in FF

var foo = function(){ return 1; };
console.log(foo()); // 1 in both Chrome and FF

if (true) {
    function foo(){ return 2; }
}
console.log(foo()); // 1 in Chrome // 2 in FF

Изменить: Второй пример точно такой же. JavaScript не имеет области блока, только уровень функции и уровень программы. "Проблема" заключается не в том, что объявление функции находится в блоке, а в том, что это не оператор верхнего уровня.

Ответ 4

Не существует определенного поведения для объявления функции, не найденного на верхнем уровне программы или на верхнем уровне тела функции. Или, скорее, указанное поведение является синтаксической ошибкой, потому что грамматика JavaScript не допускает таких объявлений функций. Причиной различного поведения является то, что браузеры исторически были повсюду на карте здесь, и они остаются такими из-за существующих сайтов, написанных с использованием определенных браузером кодов, которые не позволяют кому-либо изменить.

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

Ответ 5

fiddle. Это Undefined Поведение. Это беспорядок.

Как интерпретирует firefox, он обрабатывается другими ответами

Как хром интерпретирует его

var foo = function() { return 1 };
if (true) {
    function foo() {
        return 2;
    }
}
console.log(foo());

То, что происходит событие function foo, объявляется, а затем перезаписывается локальной переменной foo.

Это переводится в

function foo() {
    return 2;
}
var foo;
foo = function() { return 1 };
if (true) { }
console.log(foo());