Я получил неожиданный результат. Здесь код:
b = function c() {
console.log(c);
c = 3;
console.log(c);
}
b();
Я получил неожиданный результат. Здесь код:
b = function c() {
console.log(c);
c = 3;
console.log(c);
}
b();
Вы используете выражение функции :
Функция выражения:
Функция Идентификатор opt (FormalParameterList opt) {FunctionBody}
Итак, b = function c() { ... };
является абсолютно допустимым, строгим режимом или другим. То, что происходит с c
, является другим вопросом. Согласно спецификациям:
Производство FunctionExpression: Идентификатор функции ( FormalParameterList opt) {FunctionBody}
оценивается следующим образом:[...]
3. Назовите CreateImmutableBinding конкретный метод envRec передавая значение String идентификатора в качестве аргумента.
4. Пусть замыкание является результатом создания нового объекта Function как указано в 13.2 [...]
5. Вызовите метод InitializeImmutableBinding для envRec передавая значение String идентификатора и замыкание в качестве аргументов.
[...]Примечание
Идентификатор в выражении Function можно ссылаться из внутри функции FunctionExpression FunctionBody, чтобы функция называть себя рекурсивно. Однако, в отличие от FunctionDeclaration, Идентификатор в выражении Function не может ссылаться и не влияет на область применения Expression.
Итак:
c
отображается внутри функции, но не снаружиc
не может быть перезаписана внутри функции (обязательная привязка)Между тем, из приведенного ниже кода я получил право "3".
function ff() {
Это объявление функции; здесь применяются различные (и более очевидные) правила.
Вы не можете перезаписать функцию с именем variable внутри своего объявления. Имя NFE (Именованное выражение функции) не может быть перезаписано (поскольку оно является постоянным)
Это ясно, когда вы пишете в строгом режиме JS. Попробуйте пример ниже:
'use strict';
var b = function c(){
console.log(c);
c = 3; // c still is a function
console.log(c);
}
b();
Этот шаблон объявления функции, показанный в первом примере, называется NFE (с именем function expression), а другой называется объявлением функции. Большая разница в том, что в случае NFE имя функции i.e. c
в нашем случае живет только в пределах области действия. Поэтому, если вы попытаетесь называть его своим именем извне, вы получите ошибку, c is not defined
, что означает, что c
не существует глобально.
b = function c(){
console.log(c);
c=3;
console.log(c);
}
c(); //c is not defined
Теперь внимательно посмотрите на строку c=3
внутри тела функции c. Обычно этот блок кода должен был бы создать глобальную переменную именем c, вне тела функции, которое было бы доступно, вне функции. Но здесь, поскольку c
уже живет внутри области действия собственного тела, он не позволит вам объявить там, потому что это будет означать перезаписать его собственное имя, которое не допускается в случае NFE, (но допускается в случае объявления функции, т.е. второго примера). Именно поэтому код назначения c=3
здесь ничего не делает.
Чтобы понять это более подробно, вы можете обновить c=3
с помощью var c=3
, и в этом случае он позволит вам объявить локальную переменную именем c
внутри вашего тела функции, которую вы затем можете использовать внутри функция.
b = function c(){
console.log(c);
var c=3;
console.log(c);
}
b();