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