bif*_*kin 0 javascript scoping lexical node.js ecmascript-6
我试图理解ES6词法范围(使用节点运行时).考虑以下:
'use strict';
let x = 10;
function f() {
console.log(x);
console.log(y); // This should crash
}
let y = 5;
f();
Run Code Online (Sandbox Code Playgroud)
从O'Reilly的书"学习Javascript"中解释:
词法作用域意味着您定义函数的范围内的任何变量(与您调用它时相反)都在函数的范围内.
但是,当我运行此程序(通过节点)时,它输出:10 5
是不是调用console.log(y)打破了这里的词法范围规则?如果没有,为什么不呢?
编辑:为了将来参考,似乎教科书的作者(Learning Javascript 3rd Edition O'Reilly)最近在"已确认的勘误表"中将此示例列为错误.在http://www.oreilly.com/catalog/errata.csp?isbn=0636920035534
正如Benjamin Gruenbaum所提到的那样,let并const没有提升.
作为事实上,也有适用于新的规则let和const,如...
时间死区
现在,如果这些是var声明,一切都会很清楚.但随着let和const,ES6引入了时间死区的新概念.这包括一个新的,微妙的动态.
我们来看看两个例子:
经典起吊可以在这样的例子中起作用:
'use strict';
var x = 10;
console.log(x);
console.log(y); // This should NOT crash
var y = 5;
Run Code Online (Sandbox Code Playgroud)
但是如果我们var用let声明替换声明,它会崩溃:
'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;
Run Code Online (Sandbox Code Playgroud)
为什么会崩溃?
因为与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
Run Code Online (Sandbox Code Playgroud)
如果你是颠倒的顺序let y = 5;和f();,你的代码会崩溃.
| 归档时间: |
|
| 查看次数: |
1292 次 |
| 最近记录: |