Переменные, объявленные с 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 177

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([])