2016-06-12 7 views
2
if(true) { 
    tmp = 'abc'; 
    console.log(tmp);//which should throw referenceError but not 

    let tmp; 
    console.log(tmp); 

    tmp = 123; 
    console.log(tmp); 
} 

Этот код приводитПочему этот код не приводит к ReferenceError?

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

+1

Зачем это ошибка, если вы определили ее 'tmp = 'abc';' – Tushar

+0

Ваше первоначальное использование 'tmp = 'abc'' неявно объявляет var. –

+0

Пожалуйста, покажите нам настройки вашего Babel.Это определенно должно вызывать ошибку, хотя это может и не быть, если вы переводите в свободный режим. – Bergi

ответ

2

Вы правильно, в ES6 это порождает исключение. Есть две причины, почему это не для вас:

  • node.js уже реализован let - но он работает правильно только в строгом режиме. Вы должны использовать его.
  • babel, по-видимому, не переводит TDZ по умолчанию, так как он довольно сложный и приводит к длинному коду. Однако вы можете включить его с опцией es6.blockScopingTDZ/es6.spec.blockScoping (но я не уверен, что это работало только в Вавилоне 5 и что произошло в Вавилоне 6).
+0

извините, что такое TDZ? – Runjuu

+0

@Runjuu: [временная мертвая зона] (http://stackoverflow.com/q/33198849/1048572) - вещь, которая вызывает доступ к броску, несмотря на то, что является объявленной переменной. – Bergi

+0

TDZ Babel 6 все еще довольно глючит, поэтому не так много людей используют его, я думаю. – loganfsmyth

-2

Нет, это не должно вызывать опорную ошибку.

Эта переменная объявляется неявно (в глобальной области) при ее назначении.

Затем, вы объявляете переменную с тем же именем, но с более жесткой областью. Новая переменная не поднимается, поскольку объявляется с использованием let.

Я не могу дать более точный ответ, потому что вы не объяснили , почему вы считаете, что вам нужна эталонная ошибка.

+0

'let tmp;' объявляет его внутри оператора блока, а затем 'tmp = 'abc';' пытается назначить ему до того, как строка 'let tmp;' была фактически оценена, что является условием ошибки в ES6 для 'let'. – loganfsmyth

0

Заявления

tmp = 'abc'; 

не элегантный, но еще хорошо в обычном режиме (кроме пусть ключевого слова, которое не допускаются за пределами строгого режима). Он просто создаст глобальную переменную. Однако код неверен и будет вызывать ошибку только при выполнении этого кода в «строгом режиме». В этом режиме вы должны объявить все переменные с одним из этих ключевых слов:

  • вар
  • пусть
  • 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); 
 
}

+0

Я думаю, что это ошибка babel. Я запускаю этот код без «использования строгих» в хроме, он бросает ReferenceError. , когда я запускаю этот код внутри 'use strict' в babel, он по-прежнему показывает мне тот же результат – Runjuu

+0

, но если вы можете использовать ** let ** ключевое слово, это означает, что вы находитесь в строгом режиме, и вы должны увидеть эту ошибку как мы можем видеть это в приведенном выше фрагменте. Бабель ошибка? – Przemek

+0

Под «нормальным режимом» вы подразумеваете неаккуратный режим (нестрогий)? Обратите внимание, что в чистом ES6 все еще есть ошибка, только версии (V8) переносят это из-за обратной совместимости. – Bergi