2016-04-15 3 views
9

См этот код:Такэй пусть переменная из временной мертвой зоны

<script> 
 
let {foo} = null; // TypeError 
 
</script> 
 
<script> 
 
// Here I want to assign some some value to foo 
 
</script>

Первый скрипт пытается позволить объявить-foo с помощью присвоения деструктурирующего. Тем не менее, null не может быть разрушен, поэтому присваивание вызывает TypeError.

Проблема заключается в том, что тогда переменная foo объявлена, но неинициализированный, так что если во 2-й сценарии я пытаюсь ссылаться foo, он бросает:

foo = 123; // ReferenceError: can't access lexical declaration `foo' before initialization 

И let переменных не может быть повторно объявлен:

let foo = 123; // SyntaxError: redeclaration of let foo 

Есть ли способ вывести его из TDZ, чтобы я мог присваивать значения и читать их?

+0

BTW, я хочу использовать 'foo', а не обходные пути, такие как' window.foo'. – Oriol

+0

Я предполагаю, что есть что-то интересное в первом скрипте, который затрудняет проверку действительности инициализации. – Pointy

+0

@Oriol: 'window.foo' [все равно не работает] (http://stackoverflow.com/q/28776079/1048572) :-) – Bergi

ответ

2

Это невозможно. Ожидается, что временная мертвая зона и ограниченный доступ к неинициализированной переменной let неизбежны. Это запутанно и проблематично, но предназначено и ожидается.

См spec подробности:

ПРИМЕЧАНИЕ пусть и константные декларации определить переменные, которые контекстными на текущий контекст исполнения в LexicalEnvironment. Переменные создаются, когда их содержащая Лексическая среда создается, но может быть недоступна каким-либо образом, пока не будет оценена Лексическая привязка переменной. Переменной, определяемой LexicalBinding с инициализатором, присваивается значение его AssignmentExpression Initializer при анализе LexicalBinding, а не при создании переменной. Если LexicalBinding в объявлении, пусть не имеет инициализатора переменной присваивается значение не определено, когда LexicalBinding оценивается. \

Так что, если переменная не была инициализирована на объявлении (и метания до инициализации, очевидно, в результате нет инициализация), к ней нельзя получить доступ никакими средствами.

Но на самом деле ваша проблема сложнее, чем бросать вызов. Это проблема архитектуры - вы зависите от изменяемых глобальных переменных. Это большой «no no no», и вы должны реорганизовать свой код для использования явных зависимостей.

Смежные вопросы