IIFE内部的可变提升(延迟解析) [英] Variable hoisting inside IIFE (lazy parsing)
问题描述
在以下情况下,我得到一个非常奇怪的输出:
I am getting a very strange output on the below scenarios:
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)
}
任何人都可以解释一下.
Can anybody please explain.
推荐答案
您看到的与吊装无关.
您的第一个示例非常简单:
Your first example is quite straightforward:
(function test(){
var test=123;
console.log(test)
})()
您正在函数范围内创建一个名为 test
的变量(通过 var
),并为其分配一个值,然后输出该值.
You're creating a variable (via var
) called test
within the scope of the function, and assigning it a value, then outputting that value.
您的第二个示例省略了 var
:
Your second example leaves out var
:
(function test() {
test = 123;
console.log(test);
})();
...因此 test
的含义完全不同:在由命名函数表达式创建的函数中,函数的名称是解析该函数的标识符.因此,该代码中的 test
是该函数的标识符.
...and so test
has quite a different meaning: Within a function created by a named function expression, the function's name is an identifier resolving to the function. So test
in that code is an identifier for the function.
使用函数表达式时,该标识符为只读,因此您的 test = 123;
行将被忽略,而 console.log
行输出该函数的表示形式(好像根本没有 test = 123;
一样.)
That identifier is read-only when you've used a function expression, so your test = 123;
line is ignored, and the console.log
line outputs a representation of the function (as though test = 123;
weren't there at all).
I'd forgotten that identifier is read-only (when created by an expression), but it is: From the specification:
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
- 如果 FunctionExpression 的功能代码是严格模式代码,则将 strict 设置为true.否则,将 strict 设置为false.
- 让 scope 成为正在运行的执行上下文的LexicalEnvironment.
- 让 funcEnv 为NewDeclarativeEnvironment(范围).
- 让 envRec 成为 funcEnv 的EnvironmentRecord.
- 让 name 为 BindingIdentifier 的StringValue.
- 执行envRec.CreateImmutableBinding( name ,false).
- ...
- If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
- Let scope be the running execution context's LexicalEnvironment.
- Let funcEnv be NewDeclarativeEnvironment(scope).
- Let envRec be funcEnv's EnvironmentRecord.
- Let name be StringValue of BindingIdentifier.
- Perform envRec.CreateImmutableBinding(name, false).
- ...
注意步骤6:创建标识符的绑定是不可变(无法更改).
Note Step 6: The binding creating the identifier is immutable (can't be changed).
请注意,对于可变的函数声明创建的标识符(绑定)而言,这不是正确的;但是函数 expressions 和函数 declarations 对由函数名称创建的标识符的处理完全不同.(例如:函数声明将名称放在声明所在的作用域中,而函数表达式则不在.)
Note that this isn't true for the identifier (binding) created by a function declaration, which is mutable; but function expressions and function declarations treat the identifiers created by the function name completely differently. (For instance: A function declaration puts the name in scope where the declaration is, but a function expression doesn't.)
这篇关于IIFE内部的可变提升(延迟解析)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!