有TDZ为什么要提升变量
Why hoist variables when there is TDZ
ES6 标准提出了临时死区,使得在评估词法绑定之前不可能以任何方式进行变量引用。那么词法环境初始化时的变量创建意味着什么
- 程序员 ?
- 编译器 ?
使用 var
声明的变量声明以前可能对程序员有意义,但现在有了 TDZ,java 脚本是否开始像 java 那样运行?除了 javascript 解释器的工作方式之外,我们首先进行提升(结果是 TDZ)还有什么原因吗?
如果由于执行顺序在代码中稍后遇到词法绑定,即使代码在词法上出现在词法绑定之前,会发生什么情况?
let abc = f();
let b;
f(){ return b;}
java 等传统编程语言何时创建变量?什么时候遇到变量声明?或者当词法作用域被初始化时?
So what does variable creation at the time of lexical environment
initialisation mean to the programmer?
不多。程序员只打算使用声明和初始化的变量。
变量在整个范围内(从一开始)可用只意味着错误会更容易被发现,因为在初始化之前变量的使用失败(有一个例外)而不是默默地被解析为一个outer-scope(全局?)变量。这也意味着标识符,无论它在作用域中的什么地方被使用,总是引用局部变量——这正是我们对作用域的期望。
So what does variable creation at the time of lexical environment
initialisation mean to the Compiler?
词法环境在执行期间不会改变其结构。已知范围内标识符的静态解析使编译成为可能,并且执行速度更快。
作为反例,考虑这个东西:
var x = "global";
var code = "var x = 'local';";
(function() {
"use sloppy";
function test() {
console.log(x); // what do you think does `x` refer to?
} // It's hard to understand as a developer,
// now imagine being a compiler that tries to optimise `test`.
test();
eval(code);
test();
}());
What happens when a lexical binding is encountered later in the code
due to order of execution even when the code appears before it lexically?
b
在初始化之前由对 f()
的调用使用。访问它会引发 TDZ 异常。
You can try it online.
我有一种感觉,TDZ 的创建与 var 的一个非常卑微的步骤有关,而如果他们采用看似更合乎逻辑的方法,甚至不存在标识符,引擎将不得不经历更剧烈的变化。至于你的问题的第二部分,当其他语言 "create" 变量时,还有许多其他重要因素需要考虑,你似乎已经遗漏了,例如语言是解释还是编译,以及有是 "creating" 一个变量的多个不同步骤。它在许多不同的情况下表现不同,并且没有单一的答案。事实上,这是存在许多不同语言的重要原因之一。
至于您的编码问题,这取决于您何时调用 f
函数,因为函数声明是在 java 脚本中提升的。如果您在声明 b
之前调用它,那么您处于 TDZ 中并且无法引用 b
。它的行为非常类似于您只是将 return b
放在调用此函数的任何地方。
老实说,似乎对 javascript 和一般的计算机语言存在一些潜在的误解。 Javascript 不是 "behaving" 更像 java,事实上,新的 let
关键字具有非常细微的行为,例如与 [=30= 相比,可以是块作用域] java 中的声明。我建议不要试图从其他语言的角度来考虑 ES6 的变化; javascript 与许多其他语言不同,理解这些概念以及如何使用 javascript 进行编程将非常困难。
编辑:
至于为什么会有变量和函数声明提升,那就是easily googlable.
ES6 标准提出了临时死区,使得在评估词法绑定之前不可能以任何方式进行变量引用。那么词法环境初始化时的变量创建意味着什么
- 程序员 ?
- 编译器 ?
使用 var
声明的变量声明以前可能对程序员有意义,但现在有了 TDZ,java 脚本是否开始像 java 那样运行?除了 javascript 解释器的工作方式之外,我们首先进行提升(结果是 TDZ)还有什么原因吗?
如果由于执行顺序在代码中稍后遇到词法绑定,即使代码在词法上出现在词法绑定之前,会发生什么情况?
let abc = f();
let b;
f(){ return b;}
java 等传统编程语言何时创建变量?什么时候遇到变量声明?或者当词法作用域被初始化时?
So what does variable creation at the time of lexical environment initialisation mean to the programmer?
不多。程序员只打算使用声明和初始化的变量。
变量在整个范围内(从一开始)可用只意味着错误会更容易被发现,因为在初始化之前变量的使用失败(有一个例外)而不是默默地被解析为一个outer-scope(全局?)变量。这也意味着标识符,无论它在作用域中的什么地方被使用,总是引用局部变量——这正是我们对作用域的期望。
So what does variable creation at the time of lexical environment initialisation mean to the Compiler?
词法环境在执行期间不会改变其结构。已知范围内标识符的静态解析使编译成为可能,并且执行速度更快。
作为反例,考虑这个东西:
var x = "global";
var code = "var x = 'local';";
(function() {
"use sloppy";
function test() {
console.log(x); // what do you think does `x` refer to?
} // It's hard to understand as a developer,
// now imagine being a compiler that tries to optimise `test`.
test();
eval(code);
test();
}());
What happens when a lexical binding is encountered later in the code due to order of execution even when the code appears before it lexically?
b
在初始化之前由对 f()
的调用使用。访问它会引发 TDZ 异常。
You can try it online.
我有一种感觉,TDZ 的创建与 var 的一个非常卑微的步骤有关,而如果他们采用看似更合乎逻辑的方法,甚至不存在标识符,引擎将不得不经历更剧烈的变化。至于你的问题的第二部分,当其他语言 "create" 变量时,还有许多其他重要因素需要考虑,你似乎已经遗漏了,例如语言是解释还是编译,以及有是 "creating" 一个变量的多个不同步骤。它在许多不同的情况下表现不同,并且没有单一的答案。事实上,这是存在许多不同语言的重要原因之一。
至于您的编码问题,这取决于您何时调用 f
函数,因为函数声明是在 java 脚本中提升的。如果您在声明 b
之前调用它,那么您处于 TDZ 中并且无法引用 b
。它的行为非常类似于您只是将 return b
放在调用此函数的任何地方。
老实说,似乎对 javascript 和一般的计算机语言存在一些潜在的误解。 Javascript 不是 "behaving" 更像 java,事实上,新的 let
关键字具有非常细微的行为,例如与 [=30= 相比,可以是块作用域] java 中的声明。我建议不要试图从其他语言的角度来考虑 ES6 的变化; javascript 与许多其他语言不同,理解这些概念以及如何使用 javascript 进行编程将非常困难。
编辑:
至于为什么会有变量和函数声明提升,那就是easily googlable.