2
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) 不会抛出错误?


为什么它应该抛出一个referenceError

在 ECMAScript 2015 中,let 将变量提升到块的顶部。但是,在变量声明之前引用块中的变量会导致 ReferenceError。从块开始到处理声明,该变量处于“临时死区”中。


问题是 bable 设置,我想。
所以,也许这是通天塔的一个错误? https://github.com/babel/babel.github.io/issues/826

4

3 回答 3

2

你是对的,在 ES6 中这确实会引发异常。不适合你的原因有两个:

  • node.js 已经实现let- 但它只能在严格模式下正常工作。你应该使用它。
  • 默认情况下,babel 似乎不会转译 TDZ,因为它非常复杂并导致代码冗长。但是,您可以使用es6.blockScopingTDZ/es6.spec.blockScoping选项启用它(但我不确定这是否仅在 Babel 5 中有效,以及在 Babel 6 中发生了什么)。
于 2016-06-12T15:33:05.983 回答
0

陈述

tmp = 'abc';

不优雅但在正常模式下仍然可以(除了严格模式之外不允许的let关键字)。它只会创建全局变量。但是,代码不正确,只有在“严格模式”下执行此代码时才会抛出错误。在这种模式下,您必须使用以下关键字之一声明所有变量:

  • 变量
  • 常量

'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);
}

于 2016-06-12T15:21:09.287 回答
-2

不,它不应该引发参考错误。

当您分配给它时,该变量被隐式声明(在全局范围内)。

然后,稍后,您声明一个具有相同名称但范围更窄的变量。新变量没有被提升,因为它是使用声明的let

我无法给出更准确的答案,因为您没有解释为什么您认为应该得到参考错误。

于 2016-06-12T14:56:01.957 回答