Понимание переменных, области действия и подъема в JavaScript

Вступление

Variables являются фундаментальной частью многих языков программирования и одними из первых и наиболее важных концепций для изучения начинающими кодировщиками. В JavaScript есть ряд различных свойств переменных, а также несколько правил, которым необходимо следовать при именовании их. В JavaScript для объявления переменной используются три ключевых слова -var,let иconst - и каждое из них влияет на то, как код будет по-разному интерпретировать переменную.

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

Понимание переменных

variable - это именованный контейнер, используемый для хранения значений. Часть информации, на которую мы могли бы ссылаться несколько раз, может быть сохранена в переменной для последующего использования или изменения. В JavaScript значение, содержащееся внутри переменной, может быть любымJavaScript data type, включая число, строку или объект.

До спецификации языкаECMAScript 2015 (ES6), на которой основан современный JavaScript, был только один способ объявить переменную - использовать ключевое словоvar. В результате в большинстве старых кодов и учебных ресурсов для переменных используется толькоvar. Мы рассмотрим различия между ключевыми словамиvar,let иconst вits own section ниже.

Мы можем использоватьvar, чтобы продемонстрировать концепцию самой переменной. В приведенном ниже примере мы будемdeclare переменной, аassign ее значением.

// Assign the string value Sammy to the username identifier
var username = "sammy_shark";

Это утверждение состоит из нескольких частей:

  • Объявление переменной с использованием ключевого словаvar

  • Имя переменной (или идентификатор),username

  • Операция присваивания, представленная синтаксисом=

  • Присваиваемое значение,"sammy_shark"

Теперь мы можем использоватьusername в коде. JavaScript запомнит, чтоusername представляет собой строковое значениеsammy_shark.

// Check if variable is equal to value
if (username === "sammy_shark") {
  console.log(true);
}
Outputtrue

Как упоминалось ранее, переменные могут использоваться для представления любого типа данных JavaScript. В этом примере мы объявим переменные со значениями string, number, object, Boolean и null.

// Assignment of various variables
var name = "Sammy";
var spartans = 300;
var kingdoms = [ "mammals", "birds", "fish" ];
var poem = { roses: "red", violets: "blue" };
var success = true;
var nothing = null;

Используяconsole.log, мы можем увидеть значение, содержащееся в конкретной переменной.

// Send spartans variable to the console
console.log(spartans);
Output300

Переменные хранят данные в памяти, которые впоследствии могут быть доступны и изменены. Переменные также могут быть переназначены и им присвоено новое значение. Упрощенный пример ниже демонстрирует, как пароль может быть сохранен в переменной, а затем обновлен.

// Assign value to password variable
var password = "hunter2";

// Reassign variable value with a new value
password = "hunter3";

console.log(password);
Output'hunter3'

В реальной программе пароль, скорее всего, будет надежно храниться в базе данных. Этот пример, однако, иллюстрирует ситуацию, в которой нам может потребоваться обновить значение переменной. Значениеpassword былоhunter2, но мы переназначили его дляhunter3, которое является значением, которое JavaScript распознает с этого момента.

Именование переменных

Имена переменных в JavaScript известны какidentifiers. Мы обсудили несколько правил присвоения имен идентификаторам вUnderstanding Syntax and Code Structure in JavaScript, кратко изложенных здесь:

  • Имена переменных могут состоять только из букв (a-z), цифр (0-9), символов знака доллара ($) и подчеркивания (_)

  • Имена переменных не могут содержать никаких пробельных символов (табуляции или пробелов)

  • Числа не могут начинаться с имени любой переменной

  • Есть несколькоreserved keywords, которые нельзя использовать в качестве имени переменной

  • Имена переменных чувствительны к регистру

JavaScript также имеет соглашение об использовании верблюжьего регистра (иногда стилизованного как camelCase) в именах функций и переменных, объявленных с помощьюvar илиlet. Это практика написания первого слова строчными буквами, а затем с заглавной буквы первой буквы каждого последующего слова без пробелов между ними. Большинство переменных, которые не являются константами, будут следовать этому соглашению, за некоторыми исключениями. Имена постоянных переменных, объявленных с ключевым словомconst, обычно пишутся в верхнем регистре.

Это может показаться большим количеством правил для изучения, но это очень быстро станет второй натурой для написания допустимых и обычных имен переменных.

Разница междуvar,let иconst

В JavaScript есть три разных ключевых слова для объявления переменной, что добавляет языку дополнительный уровень сложности. Различия между тремя основаны на объеме, подъеме и переназначении.

Ключевое слово Объем Подъемно Можно переназначить Можно повторно объявить

var

Область действия функции

Yes

Yes

Yes

let

Блок область

No

Yes

No

const

Блок область

No

No

No

Вам может быть интересно, какой из трех вы должны использовать в своих собственных программах. Общепринятой практикой является максимально возможное использованиеconst иlet в случае циклов и переназначения. Как правило,var можно избежать вне работы над унаследованным кодом.

Переменная сфера

Scope в JavaScript относится к текущему контексту кода, который определяет доступность переменных для JavaScript. Два типа области:local иglobal:

  • Global variables объявлены вне блока

  • Local variables объявлены внутри блока

В приведенном ниже примере мы создадим глобальную переменную.

// Initialize a global variable
var creature = "wolf";

Мы узнали, что переменные могут быть переназначены. Используя локальную область видимости, мы можем фактически создать новые переменные с тем же именем, что и переменная во внешней области видимости, без изменения или переназначения исходного значения.

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

// Initialize a global variable
var species = "human";

function transform() {
  // Initialize a local, function-scoped variable
  var species = "werewolf";
  console.log(species);
}

// Log the global and local variable
console.log(species);
transform();
console.log(species);
Outputhuman
werewolf
human

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

Однако новые ключевые словаlet иconst - этоblock-scoped. Это означает, что новая локальная область видимости создается из любого блока, включая функциональные блоки, операторыif и циклыfor иwhile.

Чтобы проиллюстрировать разницу между переменными в функциональной и блочной области видимости, мы назначим новую переменную в блокеif, используяlet.

var fullMoon = true;

// Initialize a global variable
let species = "human";

if (fullMoon) {
  // Initialize a block-scoped variable
  let species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a human.

В этом примере переменнаяspecies имеет одно значение глобально (human) и другое значение локально (werewolf). Однако, если бы мы использовалиvar, результат был бы другим.

// Use var to initialize a variable
var species = "human";

if (fullMoon) {
  // Attempt to create a new variable in a block
  var species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a werewolf.

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

Подъемно

До сих пор в большинстве примеров мы использовали переменнуюvar доdeclare, и у нас естьinitialized со значением. После объявления и инициализации мы можем получить доступ или переназначить переменную.

Если мы попытаемся использовать переменную до того, как она будет объявлена ​​и инициализирована, она вернетundefined.

// Attempt to use a variable before declaring it
console.log(x);

// Variable assignment
var x = 100;
Outputundefined

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

// Attempt to use a variable before declaring it
console.log(x);

// Variable assignment without var
x = 100;
OutputReferenceError: x is not defined

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

Чтобы продемонстрировать эту концепцию более четко, ниже приведен код, который мы написали, и то, как на самом деле его интерпретировал JavaScript.

// The code we wrote
console.log(x);
var x = 100;

// How JavaScript interpreted it
var x;
console.log(x);
x = 100;

JavaScript сохранилx в памяти как переменную перед выполнением скрипта. Поскольку он все еще вызывался до того, как он был определен, результатом будетundefined, а не100. Однако это не вызываетReferenceError и не останавливает скрипт. Хотя ключевое словоvar на самом деле не изменило расположениеvar, это полезное представление о том, как работает подъем. Однако такое поведение может вызвать проблемы, поскольку программист, написавший этот код, вероятно, ожидает, что на выходеx будетtrue, тогда как вместо этого будетundefined.

Мы также можем увидеть, как подъем может привести к непредсказуемым результатам в следующем примере:

// Initialize x in the global scope
var x = 100;

function hoist() {
  // A condition that should not affect the outcome of the code
  if (false) {
    var x = 200;
  }
  console.log(x);
}

hoist();
Outputundefined

В этом примере мы объявилиx как100 глобально. В зависимости от оператораif,x может измениться на200, но поскольку условие былоfalse, оно не должно влиять на значениеx. Вместо этогоx был поднят на вершину функцииhoist(), и значение сталоundefined.

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

// Initialize x in the global scope
let x = true;

function hoist() {
  // Initialize x in the function scope
  if (3 === 4) {
    let x = false;
  }
  console.log(x);
}

hoist();
Outputtrue

Повторное объявление переменных, которое возможно сvar, вызовет ошибку сlet иconst.

// Attempt to overwrite a variable declared with var
var x = 1;
var x = 2;

console.log(x);
Output2
// Attempt to overwrite a variable declared with let
let y = 1;
let y = 2;

console.log(y);
OutputUncaught SyntaxError: Identifier 'y' has already been declared

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

Константы

Во многих языках программирования естьconstants, которые не могут быть изменены или изменены. В JavaScript идентификаторconst моделируется на основе констант, и значения, присвоенныеconst, не могут быть переназначены.

Обычно все идентификаторыconst пишутся в верхнем регистре. Это помечает их как легко отличимые от других значений переменных.

В приведенном ниже примере мы инициализируем переменнуюSPECIES как константу с ключевым словомconst. Попытка переназначить переменную приведет к ошибке.

// Assign value to const
const SPECIES = "human";

// Attempt to reassign value
SPECIES = "werewolf";

console.log(SPECIES);
OutputUncaught TypeError: Assignment to constant variable.

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

// Declare but do not initialize a const
const TODO;

console.log(TODO);
OutputUncaught SyntaxError: Missing initializer in const declaration

Значения, которые нельзя изменить при программировании, известны какimmutable, а значения, которые можно изменить, -mutable. Хотя значенияconst нельзя переназначить, они являются изменяемыми, поскольку можно изменять свойства объектов, объявленных с помощьюconst.

// Create a CAR object with two properties
const CAR = {
    color: "blue",
    price: 15000
}

// Modify a property of CAR
CAR.price = 20000;

console.log(CAR);
Output{ color: 'blue', price: 20000 }

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

Заключение

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

Чтобы сравнить, как переменные используются на других языках, вы можете прочитать наш учебник на «https://www.digitalocean.com/community/tutorials/how-to-use-variables-in-python-3[How To Use Variables в Python 3]. »