Переменные

Давайте для начала представим, что переменные это коробочки с именами. В дальнейшем мы можем обращаться по этому имени(идентификатору) и получать значение из этой коробочки. Операция создания переменной называется объявлением. Для того чтобы изменить значение переменной мы соответственно используем оператор назначения(=).

Переменная – это «именованное хранилище» для данных. Мы можем использовать переменные для хранения товаров, посетителей и других данных. Определение с learn.javascript.ru

Переменные объявляются с помощью операторов:

  • var - объявление переменной в старом стиле.
  • let - объявление мутабельной(изменяемой) переменной в стиле EcmaScript 2015 +
  • const - объявление константы в стиле EcmaScript 2015 +
var foo; // объявили переменную
foo = 1; // присвоили переменной значение
foo = 2; // переопределили значение переменной
console.log(bar); // попробовали обратиться к необъявленной переменной... это приведет к ошибке
var baz = 1; // объявили переменную и присвоили ей значение

Имена переменных

На имя переменной в JavaScript наложены всего три ограничения.

  1. Имя может состоять из: букв, цифр, символов $ и _
  2. Первый символ не должен быть цифрой.
  3. Имя не может быть таким же как одно из ключевых слов(операторы) break, case, catch, continue, debugger, default, delete, do, else, false, finally, for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof, var, void, while, with
Осторожно!

Будьте аккуратнее, не переопределяйте глобальные переменные, это приводит к ошибкам.

Например... Существует глобальная переменная alert(функция), это функция которая выводит текстовое сообщение в окне браузера. Если вы будете невнимательны вы можете переопределить ее и получить неожиданное поведение.

let break = 1; // ошибка!
let alert = 2;
alert(); // ошибка! теперь у нас нет такой функции alert!
Тренировочка

Какое имя разрешено, а какое нет?

let 1foo = 1;
let bar-baz = 3;
let baz = 10;
let bar10 = 20;
let null = 0;

let/const

В EcmaScript 2015 появились новые способы объявления переменных - ключевые слова let и const. Как я уже указал выше, ключевое слово let предназначено для объявления мутабельной(изменяемой) переменной, а с помощью const вы можете объявлять иммутабельные переменные(константы).

let foo; // объявили изменяемую переменную 'foo'
foo = 1; // Положили в переменную число
foo = "string"; // Положили в переменную строку
const FOO = 1; // объявили константу 'FOO'
FOO = 2; // Получим ошибку, потому как переменная FOO является константой.

Всплытие переменных(hoisting)

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

console.log(foo); // выведет в консоль undefined
var foo = 1;

Код написанный выше будет эквивалентен следующему:

var foo; // объявление
console.log(foo); // undefined
foo = 10; // присваение значения
console.log(foo); // 10

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

Совет

Принято не использовать переменные в коде, если они еще не объявлены. А вообще следует объявлять переменные в начале функции или файла.

В новом стандарте. Если переменная объявлена через let или const всплытие не произойдет.

console.log(foo); // Здесь вы получите ошибку ReferenceError foo is not defined
let foo = 1;

Константы

Константа – это переменная, которая никогда не меняется. Как правило, их называют большими буквами, через подчёркивание. Например:

const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
Обратите внимание

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

Области видимости переменных

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

Переменные в Javascript бывают глобальными и локальными. Глобальная переменная доступна везде, локальная — только в текущей области видимости.

Начиная с EcmaScript 2015 локальная область видимости разбилась на 2 части:

  • Функциональная - Область видимости переменной в рамках функции.

    function foo() {
    var bar = "bar";
    function baz() {
    console.log(bar);
    }
    }
    note

    Я выделил строки в которых переменная bar доступна.

    Переменная bar будет локальной в рамках функции foo и в рамках дочерней функциональной области (функции baz).

  • Блочная - Локальная область видимости в рамках блока(между фигурных скобок{})

    C появлением новых инструкций объявления переменных let и const, появился новый тип скоупа. Начиная с EcmaScript 2015 мы можем объявлять локальные переменные в рамках блока. Думаю что по примеру будет понятно:

    function foo() {
    {
    let bar = "bar";
    console.log(bar); // Здесь переменная bar доступна
    }
    console.log(bar); // А здесь уже нет!
    }
    note

    Я выделил строки в которых переменная bar доступна.

Ограничение видимости переменных

Глобальные переменные - это ЗЛО. Почему? Ну все просто.. зачем вам глобальная переменная, которая может случайно конфликтовать с какой-нибудь другой переменной в какой-нибудь библиотеке.. даже не в вами написанном коде. Мы достаточно легко можем представить что у вас есть глобальная переменная.

TODO

Дописать

Дополнительные материалы

Есть некоторая проблема для в понимании как связан стек вызовов и области видимости переменных(скоупы). Вот хорошая статья, которая должна это объяснить: