Книга: JavaScript. Подробное руководство, 6-е издание

11.2. Константы и контекстные переменные

11.2. Константы и контекстные переменные

Теперь оставим подмножества языка и перейдем к расширениям. В версии JavaScript 1.5 и выше появилась возможность использовать ключевое слово const для определения констант. Константы похожи на переменные, за исключением того, что попытки присваивания им значений игнорируются (они не вызывают ошибку), а попытка переопределить константу приводит к исключению:

const pi = 3.14; // Определить константу и дать ей значение.
pi = 4;          // Любые последующие операции присваивания игнорируются.
const pi = 4;    // Повторное объявление константы считается ошибкой.
var pi = 4;      // Это тоже ошибка.

Ключевое слово const действует подобно ключевому слову var: для него не существует области видимости блока и объявления константы поднимаются в начало вмещающего определения функции (раздел 3.10.1).

Отсутствие в языке JavaScript области видимости блока для переменных долгое время считали недостатком, поэтому в версии JavaScript 1.7 появилось ключевое слово let, решающее эту проблему. Ключевое слово const всегда было зарезервированным (но не используемым) словом в JavaScript, благодаря чему константы можно добавлять, не нарушая работоспособность существующего программного кода. Ключевое слово let не было зарезервировано, поэтому оно не распознается версиями интерпретаторов ниже 1.7.

Ключевое слово let имеет четыре формы использования:

• как инструкция объявления переменной, подобно инструкции var;

• в циклах for или for/in, как замена инструкции var;

• как инструкция блока, для объявления новых переменных и явного ограничения их области видимости; и

• для определения переменных, область видимости которых ограничивается единственным выражением.

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

function oddsums(n) {
  let total = 0, result=[]; // Определены в любой точке функции
  for(let х = 1; х <= n; х++) { // переменная х определена только в цикле
    let odd = 2*х-1; // переменная odd определена только в цикле
    total += odd;
    result.push(total),
  }
  // Попытка обратиться к переменной х или odd здесь
  // вызовет исключение ReferenceError return result;
}
oddsums(5); // Вернет [1,4,9,16,25]

Обратите внимание, что в этом примере инструкция let используется так же, как замена инструкции var в цикле for. Она создает переменную, которая будет доступна только в теле цикла и в выражениях проверки условия и увеличения цикла. Точно так же можно использовать инструкцию let в циклах for/infor each; раздел 11.4.1):

о = {х:1,у:2};
for(let р in о) console.log(p);      // Выведет х и у
for each(let v in о) console.log(v); // Выведет 1 и 2
console.log(p)                       // ReferenceError: p не определена

Существует одно интересное отличие между случаями, когда let используется как инструкция объявления и когда let используется как инструмент инициализации переменной цикла. При использовании let в качестве инструкции объявления значение выражения инициализации вычисляется в области видимости переменной. Но в цикле for выражение инициализации вычисляется за пределами области видимости новой переменной. Это отличие становится важным, только когда имя новой переменной совпадает с именем уже существующей переменной:

let х = 1;
for(let х = х + 1; х < 5; х++)
   console.log(x); // Выведет 2,3,4
{              // Начало блока, чтобы образовать область видимости новой переменной
let х = х + 1; // переменная х не определена, поэтому х+1 = NaN
console.log(x); // Выведет NaN
}

Переменные, объявленные с помощью инструкции var, определены в любой точке функции, где они объявлены, но они не инициализируются, пока инструкция var не будет выполнена фактически. То есть переменная существует (обращение к ней не вызывает исключение ReferenceError), но при попытке использовать переменную до инструкции var она будет иметь значение undefined. Переменные, объявляемые с помощью инструкции let, действуют аналогично: если попытаться использовать переменную до инструкции let (но внутри блока, где находится инструкция let), переменная будет доступна, но она будет иметь значение undefined.

Примечательно, что данная проблема отсутствует при использовании let для объявления переменной цикла - просто сам синтаксис не позволяет использовать переменную до ее инициализации. Существует еще один случай использования инструкции let, где отсутствует проблема использования переменной до ее инициализации. Блок, образуемый инструкцией let (в противоположность объявлению переменной с помощью инструкции let, показанному выше), объединяет блок программного кода с объявлением переменных для этого блока и их инициализацией. В этом случае переменные и выражения их инициализации заключаются в круглые скобки, за которыми следует блок инструкций в фигурных скобках:

let х=1, у=2;
let (х=х+1,у=х+2) { // Отметьте, что здесь выполняется сокрытие переменных
  console.log(х+у); // Выведет 5
};
console.log(x+y); // Выведет 3

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

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

let х=1, у=2;
console.log(let (х=х+1,у=х+2) х+у); // Выведет 5

Некоторые формы использования ключевых слов const и let (не обязательно все четыре, описанные здесь) в будущем наверняка будут включены в стандарт ECMAScript.

Версии JavaScript

В этой главе при упоминании какой-то определенной версии JavaScript подразумевается версия языка, реализованная проектом Mozilla в интерпретаторах Spider monkey и Rhino и в веб-броузере Firefox.

Некоторые расширения языка, представленные здесь, определяют новые ключевые слова (такие как let), и, чтобы избежать нарушения работоспособности существующего программного кода, использующего эти ключевые слова, JavaScript требует явно указывать версию, чтобы иметь возможность использовать расширения. Если вы пользуетесь автономным интерпретатором Spidermonkey или Rhino, версию языка можно указать в виде параметра командной строки или вызовом встроенной функции version(). (Она ожидает получить номер версии, умноженный на сто. Чтобы получить возможность использовать ключевое слово let, нужно выбрать версию JavaScript 1.7, т.е. передать функции число 170.) В Firefox указать номер версии можно в теге script:

<script type=”application/JavaScript; version=1.8">

********************

Оглавление книги


Генерация: 0.518. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз