Осваивая основы JavaScript, я наткнулся на три способа объявления переменной: var, let и const. Итак, в этой статье я попытался обобщить все свои выводы, чтобы различить каждое из заявленных заявлений.

Чтобы понять разницу между var, let и const мы должны понимать следующие четыре концепции:

  • Объявление переменной
  • Инициализация переменной
  • Сфера
  • Подъем

Объявление переменной

Объявление переменной - это процесс введения нового идентификатора в нашу программу; чтобы быть конкретным для нашей области (я расскажу об объемах позже). В JavaScript идентификаторам по умолчанию присваивается значение undefined при объявлении с ключевым словом var (это автоматически выполняется интерпретатором).

var foo; // declaration
console.log(foo); // logs-->undefined

Инициализация переменной

Инициализация переменной - это процесс первоначального присвоения значений идентификатору, поэтому, когда мы объявляем привязку с ключевым словом var, интерпретатор автоматически инициализирует его значением undefined.

var foo; //declaration
console.log(foo); // logs -->undefined

foo = "something"; // Initialization
console.log(foo); // logs -->something

Сфера

Область видимости переменной фактически определяет контекст, в котором переменные и функции доступны и на которые можно ссылаться в программе. Область видимости определяет видимость и время жизни переменных и параметров. Если переменная не находится «в текущей области», то она недоступна для использования. Области также могут быть разделены на уровни в иерархии, чтобы дочерние области имели доступ к родительским областям, но не наоборот.

По сути, существует два типа определения объема

  • объем функции
  • область действия блока

объем функции:

Переменные, объявленные внутри функции, относятся к функции и всем последующим вложенным функциям; независимо от блоков.

function foo() {

  if(true) {
    var v = "var inside the if block";
    console.log(v);  //logs -->var inside the if block
  } 
  v = "var outside the if block";
  console.log(v);  //logs -->var outside the if block
}

foo();

область действия блока

Переменные, объявленные внутри блока, ограничиваются только его блоком и всеми последующими вложенными блоками, но не вне блока, даже не в той же функции; блоки здесь включают блоки if… else или блоки цикла.

function bar() {

  if(true) {
    let l = "let inside the if block";
    console.log(l);  //logs -->let inside the if block
  }

console.log(l); // Uncaught Reference Error: l is not defined
}

bar();

Подъем:

MDN определяет подъем как:

«Подъем» - это термин, который вы не встретите ни в одной нормативной документации до ES2015 Language Specification. Подъем был задуман как общий способ размышления о том, как контексты выполнения (в частности, этапы создания и выполнения) работают в JavaScript. Однако поначалу концепция может немного сбивать с толку.

Концептуально, например, строгое определение подъема предполагает, что объявления переменных и функций физически перемещаются в начало вашего кода, но на самом деле это не то, что происходит. Вместо этого объявления переменных и функций помещаются в память на этапе компиляции, но остаются там, где вы ввели их в код ».

console.log(foo); //logs -->undefined 

//it does not throw an error but logs -->undefined;
//this happens because of hoisting

var foo = "something"; //Initialization
console.log(foo); //logs -->something

Для приведенного выше кода оценка интерпретатора JS может быть упрощена следующим образом:

var foo; // Hoisted declaration of 'foo'

console.log(foo); logs -->undefined;
foo = "something";
console.log(foo); //logs -->something

вар

Оператор var объявляет переменную, при необходимости инициализируя ее значением. Любая переменная, объявленная с помощью оператора var, имеет область видимости функции, а также идентифицирует объявленные с помощью var ключевые слова, которые поднимаются и инициализируются неопределенным значением. .

console.log(foo); //logs -->undefined
var foo;

//the above code does not throw an error because of hoisting;

позволять

Оператор let объявляет локальную переменную. Любая переменная, объявленная с помощью оператора let, имеет блочную область видимости. Идентификаторы, объявленные для ключевых слов let, поднимаются и не инициализируются.

let foo;
console.log(foo); // Uncaught Reference Error: l is not defined

//the above code throws an error because identifiers declared with let keywords are not initialized;

let привязки создаются в верхней части (блочной) области, содержащей объявление, обычно называемое «подъемом». В отличие от переменных, объявленных с помощью var, которое начинается со значения undefined, переменные let не инициализируются до тех пор, пока не будет оценено их определение. Доступ к переменной до инициализации приводит к ошибке ссылки.

const

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

По указанной выше причине привязку const всегда нужно инициализировать при объявлении, иначе это приведет к ошибке.

const foo = "something";
foo = "other thing"; // Uncaught TypeError: Assignment to constant variable.    

const bar; //Uncaught SyntaxError: Missing initializer in const declaration

ПРИМЕЧАНИЕ.
Здесь следует отметить, что когда мы используем привязку const к объекту, сам объект не может быть изменен и будет продолжать указывать на тот же объект, содержимое этого объекта может измениться.

const score = {visitors: 0, home: 0};

score.visitors = 1; // This is okay  
score = {visitors: 1, home: 1}; // Uncaught TypeError: Assignment to constant variable.
// This isn't allowed

Последний забавный факт:

Привязки, объявленные в функции без ключевого слова объявления, станут глобальной переменной. Позвольте мне объяснить это на примере:

function funFact() {
  isGloballyAvailable = true;
}
funFact();
console.log(isGloballyAvailable); // logs true

Чтобы понять это, мы должны вернуться к нашей концепции подъема, обычно происходит то, что всякий раз, когда мы инициализируем переменную в нашем коде, интерпретатор выполняет поиск поднятых переменных, а затем присваивает или переназначает значение переменной, но когда интерпретатор не может найти переменная в функции, к которой она идет, и поиск в поднятых переменных своей родительской функции, и этот процесс повторяется до глобальной области;

В нашем случае интерпретатор не найдет нашу привязку isGloballyAvailable даже в глобальной области видимости, поэтому интерпретатор автоматически добавляет переменную в глобальную область видимости.

Это чрезвычайно опасный процесс, и его следует избегать любой ценой; поэтому имейте в виду, что мы не должны объявлять привязку без: var, let или const в любом месте нашего кода.

Итак, когда мы должны использовать var, let или const?

ES2015 (ES6) представил let и const, зачем разработчикам JavaScript их вводить? может быть, чтобы исправить некоторые проблемы с var или, может быть, для лучшей читаемости… не так ли?

Одна из основных проблем с var заключается в том, что он позволяет повторно объявлять в коде, что не вызывает ошибок, которые могут создавать непредвиденные побочные эффекты в вашем коде.

Наиболее популярным и, как мне кажется, является следующее:

Мы всегда должны предпочесть const, если значение, присвоенное нашей переменной, не изменится, это говорит будущим разработчикам, что идентификатор имеет постоянное значение.
Вкл. с другой стороны, используйте let, если идентификатору потребуется изменить свое значение позже, но я не вижу варианта использования, в котором мы должны использовать var.