ES5 typeof
被认为是安全的,因为当再次检查非声明值时,不抛出ReferenceError
。比如
console.log(typeof undeclaredVar); // undefined
但是,在es6中检查typeof undeclaredLetConst
时,如果稍后使用let
或const
声明该值,则会引发错误 。如果用var声明它将正常工作。
console.log(typeof undeclaredLetConst);
let undeclaredLetConst = "hello"; // ReferenceError
那里发生了什么?
答案 0 :(得分:11)
var
声明当JavaScript引擎查看词法范围块并找到带有var
的变量声明时,它会将声明提升到函数的顶部(如果不存在"use strict"
,则将全局范围提升)。
因此,typeof
将永远不会失败,因为其检查的变量将被预先提升。
TDZ 永远不会在ECMAScript规范中明确命名,但该术语用于描述为什么let和const声明在声明之前无法访问。
const
和let
当JavaScript引擎查看词法范围块并找到带有let
或const
的变量声明时,它会将声明放在 TDZ 中。任何尝试访问 TDZ 中的变量都会导致运行时错误。
一旦流程到达声明本身,声明将在运行时期间从 TDZ 中删除。
console.log(typeof undeclaredLetConst); // "undefined"
if (1) {
let undeclaredLetConst = "no errors!";
}
执行undeclaredLetConst
操作时, typeof
不在 TDZ 中,因为它发生在声明undeclaredLetConst
的块之外。这意味着没有值绑定,typeof只返回“undefined”。
来源: Nicholas C. Zakas 的一本很棒的书,了解ECMAScript 6。