2013-01-09 3 views
11

Запуск этого в Chrome и Firefox дает разные ответы:Javascript Подъемно в Chrome и Firefox

(function() { 

     if(true) { 
      function f() { alert("yes"); }; 
     } else { 
      function f() { alert("no"); }; 
     } 
     f(); 

    })(); 

В Chrome результат «нет» В Firefox результат «да»

Почему разница ?

ответ

12

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

var f; 
if(true) { 
    f = function() { alert("yes"); }; 
} else { 
    f = function() { alert("no"); }; 
} 
f(); 

famous Kangax article on function expressions дает некоторые дополнительные детали:

FunctionDeclarations только разрешено появляться в программе или ТелоФункции. Синтаксически, они не могут появляться в блоке ({ ... }) - как, например, из if, while или for заявления. Это происходит потому, что Блоки могут содержать только заявления, а не SourceElements, который FunctionDeclaration есть.

В этой же статье говорится:

Стоит отметить, что в соответствии со спецификацией, реализации могут ввести синтаксических расширений (смотрите раздел 16), но по-прежнему полностью конформным. В наши дни это происходит именно так. Некоторые из них интерпретируют объявления функций в блоках как любые другие объявления функций - просто поднимая их на вершину охватывающей области; Другие - вводят различную семантику и следуют несколько более сложным правилам.

5

От V8 (Chrome двигателя JavaScript) bug tracker:

Не ошибка. Firefox - единственный браузер, который делает то, что вы ожидаете.

Поведение Safari и IE на этом же, что и у Chrome/V8.

2

Это происходит из-за отсутствия Firefox функции подъема, как задумано в ECMAScript 5.

Хром правильно присваивает значение F() перед запуском тело функции, поэтому первый вариант F() перезаписывается вторым.

SpiderMonkey (двигатель JavaScript браузера Firefox) запускает код без предварительного assignin значения для F(), поэтому он использует единственное значение, которое встречает на своем пути: function f() { alert("yes"); };

то, что функция подъем?
Область действия функции JavaScript означает, что все переменные, объявленные внутри функции, видны по всему телу функции. Любопытно, что это означает, что переменные равно , видимым до их объявления. Эта особенность JavaScript неофициально известна под названием hoisting: Код JavaScript ведет себя так, как будто все объявления переменных в функции (но не любые связанные назначения) «поднимаются» вверху функции.

источники:
http://statichtml.com/2011/spidermonkey-function-hoisting.html
2011 - O'Reilly - JavaScript - полное руководство шестых издание

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