我在下面的场景中得到了一个非常奇怪的输出:
function test(){
var test=123;
console.log(test)
}
// this output : 123
(function test(){
var test=123;
console.log(test)
})()
// this output: 123
但使用以下代码时
(function test(){
test=123;
console.log(test)
})()
//output:
function test(){
test=123;
console.log(test)
}
任何人都可以解释一下。
答案 0 :(得分:9)
您所看到的与吊装无关。
你的第一个例子很简单:
(function test(){
var test=123;
console.log(test)
})()
您正在函数范围内创建一个名为var
的变量(通过test
),并为其赋值,然后输出该值。
你的第二个例子没有var
:
(function test() {
test = 123;
console.log(test);
})();
...所以test
具有完全不同的含义:在由命名函数表达式创建的函数中,函数的名称是解析函数的标识符。因此,该代码中的test
是函数的标识符。
当您使用函数表达式时,该标识符为只读,因此忽略test = 123;
行,console.log
行输出函数的表示形式(好像test = 123;
根本不存在)。
我忘记了标识符是只读的(当由表达式创建时),但它是:来自the specification:
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
- 如果 FunctionExpression 的功能代码是严格模式代码,请将 strict 设为true。否则,请将 strict 设为false。
- 让范围成为正在运行的执行上下文的LexicalEnvironment。
- 让 funcEnv 成为NewDeclarativeEnvironment(范围)。
- 让 envRec 成为 funcEnv 的EnvironmentRecord。
- 让 name 为 BindingIdentifier 的StringValue。
- 执行envRec.CreateImmutableBinding( name ,false)。
- ...
醇>
注意步骤6:创建标识符的绑定是不可变(无法更改)。
请注意,对于由函数声明创建的标识符(绑定),情况并非如此,这是可变的;但函数表达式和函数声明完全不同地处理由函数名创建的标识符。 (例如:函数声明将名称放在声明所在的范围内,但函数表达式不会。)