2016-12-21 4 views
8

Недавно я столкнулся с этой странной вещью в хром-консоли. Здесь я намеренно назначаю неопределенную вещь для того, чтобы выбросить ошибку.Хром-консоль уже объявила переменные throw undefined справочные ошибки для let

let a = werwr // Uncaught ReferenceError: werwr is not defined 

Затем, когда я пытался присвоить что-то законным к, это случилось:

let a = "legit string" // Uncaught SyntaxError: Identifier 'a' has already been declared 

поэтому я не могу использовать «пусть», так как уже было объявлено. Так что я пытался передать что-то еще к «уже объявлен»

a = "legit string" // Uncaught ReferenceError: a is not defined 

Таким образом, кажется, что я не могу передать что-то еще а, но в то же время, было объявлено, так что я не могу использовать пусть снова.

Я понимаю разницу между объявлением и назначением переменной. Однако здесь кажется, что ничего нельзя сделать снова. Связано ли это с областью «let» в консоли? Поскольку же полностью работает «вар»

var a = werwr 
// Uncaught ReferenceError: werwr is not defined 

a = ”legit string“ 
// ”legit string“ 

var a = "legit string" 
// Uncaught SyntaxError: Identifier 'a' has already been declared 

Последующая деятельность

Там, кажется, какая-то разница между «вручную» грузоподъемных оператор LET против неявном случае.

throw new Error 
let example = 5 
// same errors as before 

В этом случае пример можно переназначить снова.

let example 
throw new Error 
example = 5 
+0

@JaromandaX фиксированный опечаток извините – whales

+0

выглядит как консоль в хроме в строгом режиме для запуска - аналогичные проблемы в firefox, за исключением строки 'a =" legal string "' работает каждый раз, когда –

+0

кажется, что это раздражение в хром-консоль, конечно, однако это вообще не повлияет на веб-страницу ** ** –

ответ

6

Это происходит, когда вы вводите временную мертвую зону в глобальную область действия. Как вы, возможно, знаете, let объявления are hoisted but left uninitialised. Из-за потока управления, может случиться так, что переменная никогда не инициализируется:

function …() { 
    if (false) 
     example; // would throw a ReferenceError if it was evaluated 
    … // do something 
    if (true) 
     return; // stop! 
    let example = 5; // never executed 
} 

Это нормально в области видимости функции. Возможно, что-то пошло не так, возможно, переменная не нужна вообще - в следующем вызове будет создана новая область с новой переменной.

Аналогичная вещь может произойти в глобальном масштабе, когда вы генерируете исключение, прежде чем инициализируется переменная (только исключения здесь работают как конструкция потока управления, ничто иное не достигает такого же эффекта).

throw new Error; 
let example = 5; 

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

Этот was discussed on es-discuss, но считается неуместным. Если выполнение верхнего уровня <script> вызывает ошибку, у вас больше проблем, чем неинициализированных переменных. Нет пути для восстановления. Если вам это нужно (например, попробовав повторное объявление его в последовательных сценариях), вы все равно должны использовать var.

У вас такая же проблема в консоли devtools - это немного неприятность, но может быть решена для консоли как специальная область.

+0

Учитывая, что let's hoisted, я написал код следующим образом: «let x; throw new Error; x = 6» в этом случае, x может быть переназначен позже. Есть ли какая-то тонкая разница между «ручным» подъемом операторов объявления против неявной реализации? Я добавил продолжение вопроса с лучшим форматом – whales

+0

Да, 'let x;' является ярлыком для 'let x = undefined;', и если вы поместите это в верхнем ручном режиме, вы инициализируете переменную до того, как будет получено исключение выброшены. – Bergi

+0

Re: «Нет пути для восстановления», в будущем он сможет «

1

Вы должны знать о подъеме в JS. В принципе, заявление, как этот let a = werwr;

интерпретируется как let a; a = werwr;

И почему уже объявлен при запуске второй строки кода.

UPDATE

Итак, есть примечание в ES спецификации https://tc39.github.io/ecma262/#prod-LetOrConst

пусть и константные декларации определить переменные, которые контекстными на текущий контекст исполнения в этой LexicalEnvironment. Переменные: , созданный при создании экземпляров, содержащих их Лексическую среду , но может быть недоступен каким-либо образом до тех пор, пока значение LexicalBinding переменной не будет оценено. Переменной, определяемой с помощью LexicalBinding с инициализатором , присваивается значение его присвоения присваивания инициализатора, когда оценивается LexicalBinding, а не когда создается переменная. Если Лексическая привязка в декларации let не имеет инициализатора переменной присваивается значение undefined при оценке LexicalBinding .

...

«но не могут быть доступны в любом случае, пока LexicalBinding этой переменной не оценивается» означает, что декларация должна быть успешно завершена, прежде чем вы можете получить доступ к переменной (или получать значение, присваивая значение, или делать typeof, или событие delete);

В вашем случае лексическая привязка переменной прервана из-за исключения.

let a = werwr // Uncaught ReferenceError: werwr is not defined 

Следуйте по ссылке и дайте более подробную информацию. Если вы найдете способ восстановить varaible a, скажите, пожалуйста. Спасибо, сегодня я узнал что-то новое о Javascript.

+0

, если это так, я должен был бы выполнить «a =« законную строку », но он выбросил ошибку, которая не определена, также если я пишу инструкции отдельно, как и вы, я мог бы переназначить a. Однако в моем случае это не происходит – whales

+0

Вы правы, мое последнее объяснение теперь - это инструмент разработчика Chrome. скрипт by eval(). Я пытаюсь сделать пример из этого, но с 'let' внутри eval() .... Хорошо. Удачи. – vothaison

+1

спасибо за выполнение исследования. Ответ Берги был довольно тщательным, если вас интересует – whales

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

  • Нет связанных вопросов^_^