为什么这段代码不会导致ReferenceError?

时间:2016-06-12 14:27:30

标签: javascript ecmascript-6 babel-node

from sys import argv

script, filename = argv # script = alien.py; filename = roswell.txt

listed = []

text = open(filename, 'rw')

for i in text:
    lines = readline(i)
    listed.append(lines)

print listed
text.close()

此代码导致

<div class="row" style="overflow:visible;"></div>

为什么第一个console.log(tmp)没有抛出错误?

<小时/> why it should throw a referenceError

  

在ECMAScript 2015中,让我们将变量提升到块的顶部。但是,在变量声明之前引用块中的变量会导致ReferenceError。变量位于&#34;临时死区&#34;从块的开始直到处理声明。

<小时/> 我认为问题是双重设置。 所以,也许这是一个巴贝尔的错误? https://github.com/babel/babel.github.io/issues/826

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

声明

tmp = 'abc';

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

  • VAR
  • const

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

答案 2 :(得分:-2)

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

当您赋值变量时,会隐式声明该变量(在全局范围内)。

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

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