Ответ 1
Нет, они не совпадают, хотя они оба приводят к функции, которую вы можете вызвать через символ foo
. Один - это объявление функции, другое - выражение функции. Они оцениваются в разное время, оказывают различное влияние на область, в которой они определены, и являются законными в разных местах.
Цитата мой ответ на этот другой вопрос здесь (немного отредактирован для релевантности), если другой вопрос когда-либо удалился по какой-то причине (и спасти людей, следующих за ссылка):
JavaScript имеет две разные, но связанные вещи: объявления функций и выражения функций. Между ними есть заметные различия:
Это объявление функции:
function foo() {
// ...
}
Объявления функций оцениваются при вводе в охватывающую область, перед выполнением любого пошагового кода. Имя функции (foo
) добавляется к охватывающей области (технически, переменному объекту для контекста выполнения определена функция).
Это выражение функции (в частности, анонимное, например, ваш котировочный код):
var foo = function() {
// ...
};
Функциональные выражения оцениваются как часть пошагового кода в точке, где они появляются (как и любое другое выражение). Это создает функцию без имени, которое она присваивает переменной foo
.
Выражения функции также могут быть названы, а не анонимными. Именованный выглядит следующим образом:
var x = function foo() { // Valid, but don't do it; see details below
// ...
};
Именованное выражение функции должно быть действительным, согласно спецификации. Он должен создать функцию с именем foo
, но не помещать foo
в область приложения, а затем назначить эту функцию переменной x
(все это происходит, когда выражение встречается в пошаговом режиме, код шага). Когда я говорю, что он не должен помещать foo
в охватывающую область, я имею в виду именно это:
var x = function foo() {
alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo); // alerts "undefined" (in compliant implementations)
Обратите внимание, как это отличается от того, как работают объявления функций (где имя функции добавлено в область приложения).
Именованные функциональные выражения работают над совместимыми реализациями, но в реализациях в дикой природе было несколько ошибок, особенно Internet Explorer 8 и более ранних версий (и некоторые ранние версии Safari). IE8 обрабатывает именованное выражение функции дважды: сначала как объявление функции (при входе в контекст выполнения), а затем позже как выражение функции, генерируя две различные функции в процессе. (Действительно.)
Подробнее здесь: Двойной выбор и здесь: Именованные функциональные выражения, демистифицированные
ПРИМЕЧАНИЕ.. Ниже было написано в 2011 году. В 2015 году объявления функций в блоках управления были добавлены в язык как часть ECMAScript 2015. Их семантика варьируется в зависимости от того, находитесь ли вы в строгом или строгом рыхлый режим и в свободном режиме, если среда является веб-браузером. И, конечно же, зависит ли используемая вами среда от правильной поддержки определения ES2015 для них. (К моему удивлению, на момент написания этой статьи в июле 2017 года, Babel также не переводит их.) Следовательно, вы можете только надежно использовать объявления функций в структурах потока управления в определенных ситуациях, поэтому, вероятно, сейчас лучше использовать выражения функций.
<ы > И, наконец, другая разница между ними заключается в том, где они законные. Выражение функции может появляться в любом месте, где может появляться выражение (что практически где угодно). Объявление функции может отображаться только на верхнем уровне его охватывающей области, вне любых операторов потока управления. Так, например, это действительно:
function bar(x) {
var foo;
if (x) {
foo = function() { // Function expression...
// Do X
};
}
else {
foo = function() { // ...and therefore legal
// Do Y
};
}
foo();
}
... но это не так, а не делает делать то, что похоже на большинство реализаций:
function bar(x) {
if (x) {
function foo() { // Function declaration -- INVALID
// Do X
}
}
else {
function foo() { // INVALID
// Do Y
}
}
foo();
}
И это имеет смысл: поскольку декларации функций foo
оцениваются при входе в функцию bar
, перед выполнением любого пошагового кода интерпретатор понятия не имеет, для чего foo
для оценки. Это не проблема для выражений, поскольку они выполняются во время потока управления.
Поскольку синтаксис недействителен, реализации могут делать то, что они хотят. Я никогда не встречал того, что делал то, что я ожидал бы, и это должно было бы вызвать синтаксическую ошибку и потерпеть неудачу. Вместо этого почти все они просто игнорируют операторы потока управления и делают то, что они должны делать, если на верхнем уровне есть две объявления функции foo
(которая использует вторую, что в спецификации). Поэтому используется только второй foo
. Firefox SpiderMonkey - выдающийся, он (эффективно) преобразует их в выражения, и поэтому он использует значение x
. Живой пример.С >