ES6 / Node 中的词法范围
Lexical scoping in ES6 / Node
我正在尝试理解 ES6 词法范围(使用节点 运行time)。
考虑以下因素:
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should crash
}
let y = 5;
f();
从 O'Reilly 书中转述 "Learning Javascript":
Lexical scoping means whatever variables are in scope where you define a function from (as opposed to when you call it) are in scope in the function.
然而,当我运行这个程序(通过节点)时,它输出:
10
5
这里调用 console.log(y) 是不是违反了词法范围规则?如果不是,为什么不呢?
编辑:为了将来参考,教科书(Learning Javascript 第 3 版 O'Reilly)的作者最近在 "Confirmed Errata" 中将此示例列为错误。在 http://www.oreilly.com/catalog/errata.csp?isbn=0636920035534
正如 Benjamin Gruenbaum 所提到的,let
和 const
根本没有提升。
事实上,有适用于 let
和 const
的新规则,例如...
时间死区
现在,如果这些是 var
声明,一切就都清楚了。但是随着 let
和 const
,ES6 引入了 temporal dead zone. 的新概念,这包括一个新的、微妙的动态。
我们来看两个例子:
经典提升将在这样的示例中工作:
'use strict';
var x = 10;
console.log(x);
console.log(y); // This should NOT crash
var y = 5;
但是如果我们用 let
声明替换 var
声明,它会崩溃:
'use strict';
let x = 10;
console.log(x);
console.log(y); // This crashes: ReferenceError: can't access lexical declaration `y' before initialization
let y = 5;
为什么会崩溃?
因为与var
赋值不同,在实际let
语句之前访问使用let
定义的变量是无效的(它们处于临时死区)。
2。这种情况下的时间死区
然而,在这种情况下,暂时死区不是问题。为什么?
因为虽然我们事先用 console.log(y)
语句定义函数,但实际的函数调用和变量访问只发生在代码的末尾。所以变量绑定只在此时进行评估(再次感谢@BG):
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should not yet crash
}
let y = 5;
f(); // console.log(y) is only called here
如果您颠倒 let y = 5;
和 f();
的顺序,您的代码将会崩溃。
我正在尝试理解 ES6 词法范围(使用节点 运行time)。 考虑以下因素:
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should crash
}
let y = 5;
f();
从 O'Reilly 书中转述 "Learning Javascript":
Lexical scoping means whatever variables are in scope where you define a function from (as opposed to when you call it) are in scope in the function.
然而,当我运行这个程序(通过节点)时,它输出: 10 5
这里调用 console.log(y) 是不是违反了词法范围规则?如果不是,为什么不呢?
编辑:为了将来参考,教科书(Learning Javascript 第 3 版 O'Reilly)的作者最近在 "Confirmed Errata" 中将此示例列为错误。在 http://www.oreilly.com/catalog/errata.csp?isbn=0636920035534
正如 Benjamin Gruenbaum 所提到的,let
和 const
根本没有提升。
事实上,有适用于 let
和 const
的新规则,例如...
时间死区
现在,如果这些是 var
声明,一切就都清楚了。但是随着 let
和 const
,ES6 引入了 temporal dead zone. 的新概念,这包括一个新的、微妙的动态。
我们来看两个例子:
经典提升将在这样的示例中工作:
'use strict';
var x = 10;
console.log(x);
console.log(y); // This should NOT crash
var y = 5;
但是如果我们用 let
声明替换 var
声明,它会崩溃:
'use strict';
let x = 10;
console.log(x);
console.log(y); // This crashes: ReferenceError: can't access lexical declaration `y' before initialization
let y = 5;
为什么会崩溃?
因为与var
赋值不同,在实际let
语句之前访问使用let
定义的变量是无效的(它们处于临时死区)。
2。这种情况下的时间死区
然而,在这种情况下,暂时死区不是问题。为什么?
因为虽然我们事先用 console.log(y)
语句定义函数,但实际的函数调用和变量访问只发生在代码的末尾。所以变量绑定只在此时进行评估(再次感谢@BG):
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should not yet crash
}
let y = 5;
f(); // console.log(y) is only called here
如果您颠倒 let y = 5;
和 f();
的顺序,您的代码将会崩溃。