我看到下面有人发布的代码。我对它记录的内容感到困惑。它记录变量a
的函数,而不是200。为什么?
var a = 1;
(function a() {
a = 200;
console.log(a)
})()
答案 0 :(得分:19)
因为立即调用的函数命名为 ,并且该名称不能重新分配为直接引用IIFE中的其他 。
任何命名的函数表达式也将表现出这种行为。函数名为a
的函数表达式将意味着直接在函数内部的a
将始终引用函数本身,即使您尝试重新分配它。
如果使用严格模式,则可以使错误明确显示:
'use strict';
var a = 1;
(function a() {
a = 200;
console.log(a)
})()
未捕获的TypeError:分配给常量变量。
具有命名函数表达式有点像具有
(function a() {
const a = <this function>;
// ...
})()
除非尝试重新分配,否则只会在严格模式下抛出。
具体来说,我相信ECMAScript 5规范对此行为在SetMutableBinding中:
- 如果envRec中N的绑定是可变绑定,请将其绑定值更改为V。
- 否则,这必须是尝试更改不可变绑定的值的方法,因此如果S(使用严格模式)为true,则抛出TypeError异常。
但是直接在函数内部,函数名称绑定是不可变的-请参见Function Definition:
生产
FunctionExpression : function Identifier ( FormalParameterListopt ) { FunctionBody }
评估如下:
调用envRec的 CreateImmutableBinding 具体方法,将
Identifier
的String值作为参数传递。