Введение

Определение переменных - важная часть написания любого приложения. Переменные можно рассматривать как проводники или каналы, по которым могут передаваться данные. В этом смысле понимание того, как определять переменные, может существенно повлиять на производительность вашего приложения. JavaScript уникален тем, что имеет множество исключений, когда дело касается переменных.

Области применения

Чтобы получить более четкое представление, мы должны ввести области (также известные как блоки). Области действия можно понимать как папки (в файловой системе вашего компьютера). Используя аналогию с папками, представьте, что вы создаете папку с именем scope1 и начинаете помещать в нее файлы v1, v2, v3, v4. Каталог в этой папке будет выглядеть так…

● scope1 / v1

● scope1 / v2

● scope1 / v3

● scope1 / v4

Давайте немного изменим это: давайте заменим косую черту (/) точкой (.). Затем объявим scope1 (аналогично папке). Теперь у нас есть следующие…

● let scope1 = {};

● scope1.v1

● scope1.v2

● scope1.v3

● scope1.v4

Вам это знакомо? Должен, это JavaScript. Существует прямое соответствие между нашей структурой папок и синтаксисом JavaScript для доступа к переменным через объект (или, в данном случае, область видимости). Вы можете пойти дальше, введя вложенную область видимости в scope1. Это аналог подпапки.

● scope1.nested1 = {}

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

Так почему это важно? Области видимости используются везде в JavaScript. Например, тело функции - это область видимости. IIFE (немедленно вызываемые функциональные выражения) и классы (в ES6) используют исключительно области видимости. Циклы и операторы if также используют области видимости. Практически все, что заключено в фигурные скобки {}, заключено в область видимости. Сам объект в JavaScript состоит из области видимости. Области видимости важны, потому что они могут упорядочивать переменные, что делает их более предсказуемыми как для вас, так и для интерпретатора.

Var

Но давайте сделаем шаг назад; потому что на самом деле var работает не совсем так. К сожалению, ключевое слово var, которое JavaScript изначально использовал для объявления переменных, содержит ловушки и коварство для тех, кто не знает.

Подводные камни: подъем по умолчанию для петель

Возьмем, к примеру, этот фрагмент, который включает логику цикла for:

  1. for (var i = 0; i ‹10; ++ i) {
  2. console.log (я);
  3. }

Это выглядит достаточно просто. Он печатает

0

1

2

3

4

5

6

7

8

9

Хорошо, но добавим, давайте добавим еще один console.log (i) в строку 4. Вот так ...

  1. for (var i = 0; i ‹10; ++ i) {
  2. console.log (я);
  3. }
  4. console.log (i);

Как ты думаешь, что произойдет? Давайте остановимся и подумаем об этом на секунду. Объявление i должно находиться в рамках цикла for, поэтому его печать должна дать нам неопределенный результат.

0

1

2

3

4

5

6

7

8

9

9

Как видно из результатов, наша переменная i находится за пределами цикла for. Это не ожидаемый результат для большинства языков программирования на основе c. Причина, по которой это происходит, заключается в том, что, когда мы используем var в цикле for, javascript фактически запускает код, скорее, так ...

  1. var i = 0;
  2. while (i ‹10) {
  3. console.log (я);
  4. i++
  5. }
  6. console.log (я);

Да, вы правильно это увидели! Именно так javascript будет читать цикл for при использовании var. Это также называется подъемом, поскольку при этом переменная i выходит за пределы цикла for.

Подводные камни: подъем по умолчанию для необъявленных переменных

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

  1. function isEven (n) {
  2. if (n % 2 == 0) {
  3. var msg = «Ваш ввод четный.»;
  4. } еще {
  5. var msg = «Ваш ввод нечетный.»;
  6. }
  7. return msg;
  8. }

Обратите внимание, что var msg объявляется дважды: один раз в области действия предложения if и снова внутри предложения else. Однако обратите внимание, что в строке 9 он возвращается, как если бы он был объявлен. Это должно быть неверно, поскольку мы не объявляли msg вне области действия предложения if или else. Тем не менее, из-за поведения подъема по умолчанию, JavaScript будет вытягивать сообщение в начало нашей функции isEven, что отличается от того, что мы видели ранее в цикле for. Следующее на самом деле больше похоже на то, что на самом деле делает JavaScript.

  1. function isEven (n) {
  2. var msg = ‘’;
  3. if (n % 2 == 0) {
  4. msg = «Ваш ввод четный.»;
  5. } еще {
  6. msg = «Ваш ввод нечетный.»;
  7. }
  8. return msg;
  9. }

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

  1. p = «Я устанавливаю значение p, которое не было официально объявлено var»;
  2. console.log (p); // это работает нормально
  3. var p = "Теперь мы объявляем это".

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

  1. var p = ‘’;
  2. p = «Я устанавливаю значение p, которое формально не было объявлено var»;
  3. console.log (p); // это работает нормально
  4. p = "Теперь мы объявляем это".

Чтобы избежать этого странного поведения, мы будем использовать «use strict» в верхней части нашего документа с кодом. Это было введено в ECMA5 для ключевого слова var.

Так почему же используется подъемник?

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

Это без подъема…

  1. var favourite_numbers = [1, 8, 1988, 4];
  2. for (var i = 0; i ‹favourite_numbers.length; ++ i) {
  3. var double_len = избранное_числа * 2;
  4. var current = любимые_числа [я];
  5. console.log (double_len * текущий);
  6. }

Обратите внимание, что double_len вычисляется с одним и тем же значением для каждой итерации. В этой операции нет необходимости, поскольку наше значение каждый раз одно и то же. Мы можем уменьшить эту итерацию с i (количество элементов в списке) до постоянной 1 раз, подняв ее так…

  1. var favourite_numbers = [1, 8, 1988, 4];
  2. var double_len = любимые_числа * 2;
  3. for (var i = 0; i ‹favourite_numbers.length; ++ i) {
  4. var current = любимые_числа [я];
  5. console.log (double_len * текущий);
  6. }

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

Устранение ошибок и ECMA6

Такое поведение очень необычно, и это также делает JavaScript непривлекательным языком. Даже опытным программистам, которые погружаются в JavaScript, не зная об этих подводных камнях, будет очень сложно понять, почему их код ведет себя так странно. Чтобы исправить это, существует несколько стандартов, которые пытаются решить эти проблемы. JavaScript на самом деле является производным (диалектом) ECMAScript. ECMAScript определяет полный набор стандартов для языка. JavaScript является производным от ECMAScript в том смысле, что он наследует подмножество функций ECMAScript для работы со стандартами HTML5. И ECMAScript, и HTML5 отвечают за определение стандартов для JavaScript.

Ключевое слово let и "Строгое использование"

Было несколько серьезных проблем с ключевым словом var, поскольку его поведение по умолчанию - подъем. Это позволило переменным существовать за пределами своей локальной области видимости, как мы упоминали ранее, возникло много странного поведения, например:

● Переменные можно назначать до объявления.

● Переменные в циклах for продолжают существовать после завершения цикла.

● Переменные внутри операторов if поднимаются за пределы родительской области.

● Возможно повторное объявление переменной.

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

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

Оператор ‘use strict’ ​​, помещенный в верхней части документа с кодом, не позволит var объявлять ваши переменные перед использованием и повторно объявлять ваши переменные с помощью var. Это была первая попытка исправить опасное поведение var.

Большей части непредсказуемости и головной боли с var можно избежать, просто используя вместо этого ключевое слово let. В принципе, вам не понадобится оператор «use strict», если вы используете let вместо var, однако многие люди по-прежнему используют оператор в верхней части своих документов, если когда-либо используется var.

Итак, как именно работает ключевое слово let?

Привязки блоков, элементы в фигурных скобках {…}, такие как тело функций, операторов if и цикла for, теперь ведут себя более адекватно, как и большинство языков на основе C. . Объявление переменной с использованием ключевого слова let разрешит доступ только внутри области блока или внутри дочерних областей, она не будет доступна извне привязки блока.

Ниже показаны различия между var и let

var пример

если (правда) {
var i = 2;
}

console.log (я); // отображает 2

let пример

если правда) {

пусть j = 4;

}

console.log (j); // отображает неопределенное

Как и ожидалось, объявление var поднимает переменную за пределы области действия тела оператора if, поэтому console.log отображает значение 2, даже если оно было определено в другом сфера. С другой стороны, j был определен с использованием ключевого слова let, поэтому он не поднимался за пределы тела функции if, поэтому j недоступен за пределами тела if функция, поэтому она не определена.

Ниже показано, как ключевое слово let позволяет дочерним областям видимости по-прежнему иметь доступ к своим родительским объявленным переменным (опять же, как и в большинстве языков на основе c) ...

Привязки области видны от родителя к потомку.

for (let i = 0; i ‹400; ++ i) {

если правда) {

console.log (я);

}

}

Это тривиальный пример, который выполняет итерацию от 0 до 399 и выводит i на каждой итерации. Когда вы выполните код, вы заметите, что, хотя i был объявлен в родительской области, он по-прежнему доступен из тела оператора if, который вложен на один уровень глубже. Дочерние области имеют доступ к декларациям своих родителей.

Введение модификатора const

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

Чтобы проиллюстрировать, скажем, у нас есть несколько предопределенных переменных ...

пусть я = -1;

пусть j = 2;

пусть k = 33;

следующее будет приемлемо

const a = 0;

const b = j; // j был определен ранее

const c = 1,22;

const d = a;

Следующее неприемлемо

а = я; // это уже было объявлено

const e; // вы должны объявить и присвоить его в одной строке

const a = 100; // он уже был объявлен, вы не можете повторно объявить его

Это должно быть довольно легко понять, но разработчики на основе C из таких языков, как C ++, Java или C #, будут немного вздрагивать, увидев это. Почему? Поскольку ключевое слово const в этих языках подразумевает константы времени компиляции; это означает, что они объявляются еще до того, как приложение начнет компилироваться, поэтому вы не можете присвоить константу переменной. Это позволяет компиляторам более эффективно прогнозировать и оптимизировать приложения. Однако, поскольку JavaScript интерпретируется, он будет выполнять код построчно во время выполнения, а не компилировать все вместе в двоичный файл. Таким образом, ключевое слово const действует больше как свойство, доступное только для чтения, а не как истинная константа. Если вы не понимаете этого различия, не беспокойтесь, оно предназначено для людей, пришедших из других языков с ключевым словом const.

Итак, почему вам следует использовать ключевое слово const?

Специально: когда вы объявляете что-то вроде числа "пи" или "е" и не хотите, чтобы оно было случайно изменено вами или кем-либо еще. Он также используется, когда вы объявляете объект и не собираетесь его изменять, например, при объявлении указателя this в качестве модели представления или при ссылке на объект, который вы не хотите изменять.

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

Ключевое слово var - это немного странный, но очень важный аспект JavaScript. Базовое понимание JavaScript важно для написания надежных приложений. ECMA6 все еще является новым по сравнению с основной частью кода JavaScript, существовавшей до введения ключевого слова let. Это означает, что по-прежнему очень важно понимать, как работает var, потому что вам, возможно, придется работать с устаревшим кодом, который использует var; кроме того, поскольку пока нет намерения отказываться от поддержки var, к сожалению, некоторые разработчики JavaScript все еще будут использовать var, поэтому вы все равно можете столкнуться с ним снова.

Если вам нравится это видео, подпишитесь на нашу страницу в FaceBook на канале fb.com/intully или на наш канал в описании. Если вы хотите большего, подпишитесь на нашу новостную рассылку на intully.com, где мы будем анонсировать ранние выпуски видео в виде полнометражных видеороликов всего нашего контента, а также эксклюзивные упражнения, призванные помочь вам лучше понять этот контент. .