Осваивая основы 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.