为什么此代码不会导致 ReferenceError?
Why does this code not result in a ReferenceError?
if(true) {
tmp = 'abc';
console.log(tmp);//which should throw referenceError but not
let tmp;
console.log(tmp);
tmp = 123;
console.log(tmp);
}
此代码导致
abc
undefined
123
为什么第一个 console.log(tmp) 没有抛出错误?
why it should throw a referenceError
In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.
我认为问题是bable设置。
所以,也许这是 babel 的一个错误?
https://github.com/babel/babel.github.io/issues/826
不,它不应该引发引用错误。
当你赋值给它时,变量被隐式声明(在全局范围内)。
然后,稍后,您声明一个 new 具有相同名称但范围更小的变量。新变量未提升,因为它是使用 let
.
声明的
我无法给出更准确的答案,因为你没有解释为什么你认为你应该得到一个引用错误。
声明
tmp = 'abc';
不优雅但在正常模式下仍然可以( 除了 let 关键字在严格模式 之外是不允许的。它只会创建全局变量。但是,代码不正确,只有当您在 "strict mode" 中执行此代码时才会抛出错误。在这种模式下,您必须使用以下关键字之一声明所有变量:
- 变量
- 让
- 常数
'use strict'
if(true) {
tmp = 'abc';
console.log(tmp);//which should throw referenceError and now it does
let tmp;
console.log(tmp);
tmp = 123;
console.log(tmp);
}
你是对的,在 ES6 中这确实会抛出异常。它不适合您的原因有两个:
- node.js 已经实现
let
- 但它只能在严格模式下正常工作。你应该使用它。
- babel 似乎默认不会转译 TDZ,因为它非常复杂并且会导致冗长的代码。但是,您可以使用
es6.blockScopingTDZ
/es6.spec.blockScoping
选项启用它(但我不确定这是否仅在 Babel 5 中有效以及在 Babel 6 中发生了什么)。
if(true) {
tmp = 'abc';
console.log(tmp);//which should throw referenceError but not
let tmp;
console.log(tmp);
tmp = 123;
console.log(tmp);
}
此代码导致
abc
undefined
123
为什么第一个 console.log(tmp) 没有抛出错误?
why it should throw a referenceError
In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.
我认为问题是bable设置。
所以,也许这是 babel 的一个错误? https://github.com/babel/babel.github.io/issues/826
不,它不应该引发引用错误。
当你赋值给它时,变量被隐式声明(在全局范围内)。
然后,稍后,您声明一个 new 具有相同名称但范围更小的变量。新变量未提升,因为它是使用 let
.
我无法给出更准确的答案,因为你没有解释为什么你认为你应该得到一个引用错误。
声明
tmp = 'abc';
不优雅但在正常模式下仍然可以( 除了 let 关键字在严格模式 之外是不允许的。它只会创建全局变量。但是,代码不正确,只有当您在 "strict mode" 中执行此代码时才会抛出错误。在这种模式下,您必须使用以下关键字之一声明所有变量:
- 变量
- 让
- 常数
'use strict'
if(true) {
tmp = 'abc';
console.log(tmp);//which should throw referenceError and now it does
let tmp;
console.log(tmp);
tmp = 123;
console.log(tmp);
}
你是对的,在 ES6 中这确实会抛出异常。它不适合您的原因有两个:
- node.js 已经实现
let
- 但它只能在严格模式下正常工作。你应该使用它。 - babel 似乎默认不会转译 TDZ,因为它非常复杂并且会导致冗长的代码。但是,您可以使用
es6.blockScopingTDZ
/es6.spec.blockScoping
选项启用它(但我不确定这是否仅在 Babel 5 中有效以及在 Babel 6 中发生了什么)。