Переменные, объявленные с 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
в этом вопросе?нет, они работают так же, как и подъем рассматривается. Единственная разница между ними заключается в том, что
const
ant должен быть и может быть назначен только в инициализаторе части объявления (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([])