ES6 中的点1-块级作用域
在块级作用域中:
除了对应的let const 有作用域外,函数声明同样被限制在声明他的语句中:
使用 function :
foo('outside'); // TypeError: foo is not a function { function foo(location) { console.log('foo is called ' + location); } foo('inside'); // 正常工作并且打印 'foo is called inside' }
关于let 和 const 语句中的暂时性死区问题:
注意:与通过 var
声明的有初始化值 undefined
的变量不同,通过 let
声明的变量直到它们的定义被执行时才初始化。在变量初始化前访问该变量会导致 ReferenceError
。该变量处在一个自块顶部到初始化处理的“暂存死区”中。
function do_something() { console.log(bar); // undefined console.log(foo); // ReferenceError var bar = 1; let foo = 2; }
暂时死区和 typeof
与通过var
声明的变量, 有初始化值 undefined
和只是未声明的变量不同的是,如果使用typeof
检测在暂存死区中的变量, 会抛出ReferenceError
异常:
// prints out 'undefined' console.log(typeof undeclaredVariable); // results in a 'ReferenceError' console.log(typeof i); let i = 10;
暂时死区和静态作用域
由于词法作用域,表达式(foo + 55)
内的标识符foo
被认为是if块的foo变量,而不是值为33的块外面的变量foo。
在同一行,这个if块中的foo
已经在词法环境中被创建了,但是还没有到达(或者终止)它的初始化(这是语句本身的一部分)。
这个if块里的foo
还依旧在暂存死区里。
function test(){ var foo = 33; if (foo) { let foo = (foo + 55); // ReferenceError } } test();
在以下情况下,这种现象可能会使您感到困惑。 let n of n.a
已经在for循环块的私有范围内。因此,标识符n.a
被解析为位于指令本身("let n")中的“ n”对象的属性“ a”。
在没有执行到它的初始化语句之前,它仍旧存在于暂存死区中。
function go(n) { // n here is defined! console.log(n); // Object {a: [1,2,3]} for (let n of n.a) { // ReferenceError console.log(n); } } go({a: [1, 2, 3]});