Я вижу разницу в поведении между native es6 и transpiled code.
Согласно документам MDN, этот код должен приводить к ReferenceError
потому что я пытаюсь использовать let-bound variable
до ее определения.
let a = b; //expect ReferenceError at runtime
let b = 1;
Как и ожидалось, выполнение этого приводит к использованию ReferenceError
когда я запускаю его в том, что на самом деле поддерживает es6, например, в Chrome Developer Tools. Но если я передам это с помощью babel, он выдает код, который не приводит к ошибке выполнения (Live demo):
"use strict";
var a = b; //no error. Both a & b are undefined
var b = 1;
Поведение transpiled кода противоречит то, что MDN документы говорят (курсив мой):
В ECMAScript 2015,
let
привязки не подлежатVariable Hoisting
, что означает, чтоlet
декларация не двигайтесь к началу текущего контекста исполнения. Ссылка на переменную в блоке перед инициализацией приводит кReferenceError
(вопреки переменной, объявленной сvar
, которая будет иметь только неопределенное значение).
Поэтому мне интересно:
Есть ли способ получить сбой во время компиляции для этого, а не во время выполнения ReferenceError или молчащий сбой "undefined". Я замечаю, что получаю привязку времени компиляции к несуществующей переменной. Возможно, это может также потерпеть неудачу для еще не объявленной переменной?
let d = e; //compile error: e is not defined
Примечание: есть связанный вопрос, но я не думаю, что он отвечает на это (или это произошло, но я не понял).
В этом фрагменте
let a = b;
let b = 1;
b
находится во временной мертвой зоне. Такое поведение нельзя эмулировать в преобразованном коде.
Насколько мне известно, у Бабеля в настоящее время нет плагина для предупреждения этой проблемы. Пока эта проблема не будет решена с самим Babel, ее можно обнаружить с помощью правила ESLinter no-use-before-define
.