Переменные, объявленные с Let и const не подсадили в ЕС6?
я играл с ES6 некоторое время, и я заметил, что в то время как переменные объявлены с var поднимаются, как и ожидалось...
console.log(typeof name); // undefined
var name = "John";
...переменные, объявленные с помощью let или const кажется, есть некоторые проблемы с подъемом:
console.log(typeof name); // ReferenceError
let name = "John";
и
console.log(typeof name); // ReferenceError
const name = "John";
означает ли это, что переменные, объявленные с let или const не подсадили? Что здесь происходит? Есть ли разница между let и const в этом имеет значение?
3 ответа:
@thefourtheye правильно говорит, что эти переменные недоступен прежде чем они были объявлены. Однако, это немного сложнее.
переменные, объявленные с
letилиconstне подсадили? Что здесь происходит?все объявления (
var,let,const,function,function*,class)это "подсадил" в JavaScript. Это означает, что если имя объявляется в области, в которой идентификатор всегда будет ссылаться на эту конкретную переменную:x = "global"; // function scope: (function() { x; // not "global" var/let/… x; }()); // block scope (not for `var`s): { x; // not "global" let/const/… x; }это верно как для функциональных, так и для блочных областей1.
разницу между
var/function/function*заявления иlet/const/classдекларации является инициализации.
Первые инициализируются с помощьюundefinedили функция (генератор) справа, когда привязка создается в верхней части масштаб. Однако лексически объявленные переменные остаются неинициализированное. Это означает, чтоReferenceErrorисключение при попытке доступа к нему. Он будет инициализирован только тогда, когдаlet/const/classоператор оценивается, все до (выше), что называется временная мертвая зона.x = y = "global"; (function() { x; // undefined y; // Reference error: y is not defined var x = "local"; let y = "local"; }());обратите внимание, что a
let y;оператор инициализирует переменную с помощьюundefinedкакlet y = undefined;бы.в temporal мертвая зона-это не синтаксическое место, а скорее времени между созданием переменной (области) и инициализацией. Это не ошибка ссылаться на переменную в коде над объявлением, пока этот код не выполняется (например, тело функции или просто мертвый код), и он вызовет исключение, если вы получите доступ к переменной до инициализации, даже если код доступа находится ниже объявления (например, в объявлении поднятой функции это называется слишком рано).
есть ли разница между
letиconstв этом вопросе?нет, они работают так же, как и подъем рассматривается. Единственная разница между ними заключается в том, что
constant должен быть и может быть назначен только в инициализаторе части объявления (const one = 1;, иconst one;и более поздние переназначения вродеone = 2являются недействительными).1:
varобъявления все еще работают только на функциональном уровне, конечно
цитирование спецификации ECMAScript 6 (ECMAScript 2015),
letиconstдекларации,переменные создаются, когда их содержащая лексическая среда создается экземпляр, но не могут быть доступны в любом случае, пока не будет оценена LexicalBinding переменной.
Итак, чтобы ответить на ваш вопрос, да,
letиconstподъем, но вы не можете получить к ним доступ до фактического объявления оценивается во время выполнения.
ES6представляетLetпеременные, которые приходят сblock level scoping. ПокаES5у нас не былоblock level scoping, поэтому переменные, объявленные внутри блока, всегдаhoistedдля определения области действия уровня.в принципе
Scopeотносится к тому, где в вашей программе видны ваши переменные, что определяет, где вы можете использовать переменные, которые вы объявили. ВES5у нас естьglobal scope,function scope and try/catch scopeСES6мы также получаем область видимости уровня блока с помощью Let.
- при определении переменной с помощью
varключевое слово, это известно всю функцию с момента ее определения.при определении переменной с помощью
letоператор это известно только в блоке он определен.function doSomething(arr){ //i is known here but undefined //j is not known here console.log(i); console.log(j); for(var i=0; i<arr.length; i++){ //i is known here } //i is known here //j is not known here console.log(i); console.log(j); for(let j=0; j<arr.length; j++){ //j is known here } //i is known here //j is not known here console.log(i); console.log(j); } doSomething(["Thalaivar", "Vinoth", "Kabali", "Dinesh"]);если вы запустите код, вы можете увидеть переменную
jизвестно только вloop, а не до и после. Тем не менее, наша переменнаяiизвестно вentire functionС момента это определяется вперед.есть еще одно большое преимущество, используя давайте как создает новую лексическую среду, а также связывает новое значение, а не сохраняет старую ссылку.
for(var i=1; i<6; i++){ setTimeout(function(){ console.log(i); },1000) } for(let i=1; i<6; i++){ setTimeout(function(){ console.log(i); },1000) }первый
forцикл всегда печатать последние значением, сletон создает новую область и связывает свежие значения, печатая нас1, 2, 3, 4, 5.придя к
constants, он работает в основном какlet, единственная разница их значение не может быть изменено. В константах мутация разрешена, но переназначение не допускается.const foo = {}; foo.bar = 42; console.log(foo.bar); //works const name = [] name.push("Vinoth"); console.log(name); //works const age = 100; age = 20; //Throws Uncaught TypeError: Assignment to constant variable. console.log(age);если константа относится к
object, он всегда будет относиться кobjectноobjectсам может быть изменен (если он изменчив). Если вы хотите иметь неизменныйobject, вы могли бы использоватьObject.freeze([])