Чтение онлайн

на главную - закладки

Жанры

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

В следующем фрагменте переменные i, j и к объявляются в разных местах, но все они имеют одну и ту же область видимости - все три переменные доступны из любого места в теле функции:

function test(o) {

var і = 0; // і определена в теле всей функции

if (typeof о == "object") {

var j = 0; // j определена везде, не только в блоке

for(var k=0; k < 10; k++) { // к определена везде, не только в цикле

console.log(k); // выведет числа от 0 до 9

}

console.log(k); // к по-прежнему определена: выведет 10

}

console.log(j); // j определена, но может быть неинициализирована

}

Область видимости функции в языке JavaScript подразумевает, что все переменные, объявленные внутри функции, видимы везде в теле функции. Самое интересное, что переменные оказываются видимыми еще до того, как будут объявлены. Эта особенность JavaScript неофициально называется подъемом: программный код JavaScript ведет себя так, как если бы все объявления переменных внутри функции (без присваивания инициализирующих значений) «поднимались» в начало функции. Рассмотрим следующий фрагмент:

var scope = "global";

function f {

console.log(scope); // Выведет "undefined", а не "global"

var scope = "local"; // Инициализируется здесь, а определена везде

console.log(scope); // Выведет "local"

}

Можно было бы подумать, что первая инструкция внутри функции должна вывести слово «global», потому что инструкция

var
с объявлением локальной переменной еще не была выполнена. Однако вследствие действия правил области видимости функции выводится совсем другое значение. Локальная переменная определена во всем теле функции, а это означает, что глобальная переменная с тем же именем оказывается скрытой для всей функции. Хотя локальная переменная определена во всем теле функции, она остается неинициализированной до выполнения инструкции
var
. То есть функция выше эквивалентна реализации, приведенной ниже, в которой объявление переменной «поднято» в начало функции, а инициализация переменной выполняется там же, где и раньше:

function f {

var scope; // Объявление локальной переменной в начале функции

console.log(scope); // Здесь она доступна, но имеет значение "undefined"

scope = "local"; // Здесь она инициализируется и получает свое значение

console.log(scope); // А здесь она имеет ожидаемое значение

}

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

3.10.2. Переменные как свойства

При объявлении глобальной переменной в JavaScript в действительности создается свойство глобального объекта (раздел 3.5). Если глобальная переменная объявляется с помощью инструкции

var
, создается ненастраиваемое свойство (раздел 6.7), т. е. свойство, которое невозможно удалить с помощью оператора
delete
. Как уже отмечалось выше, если не используется строгий режим и необъявленной переменной присваивается некоторое значение, интерпретатор JavaScript автоматически создает глобальную переменную. Переменные, созданные таким способом, становятся обычными, настраиваемыми свойствами глобального объекта и могут быть удалены:

var truevar = 1; // Правильно объявленная глобальная переменная, неудаляемая.

fakevar = 2; // Создается удаляемое свойство глобального объекта.

this.fakevar2 = 3; // То же самое.

delete truevar // => false: переменная не была удалена

delete fakevar // => true: переменная удалена

delete this.fakevar2 // => true: переменная удалена

Глобальные переменные в языке JavaScript являются свойствами глобального объекта, и такое положение вещей закреплено в спецификации ECMAScript. Это не относится к локальным переменным, однако локальные переменные можно представить как свойства объекта, ассоциированного с каждым вызовом функции. В спецификации ECMAScript 3 этот объект называется «объектом вызова» (

call object
), а в спецификации ECMAScript 5 он называется «записью с описанием окружения» (
declarative environment record
). Интерпретатор JavaScript позволяет ссылаться на глобальный объект с помощью ключевого слова this, но он не дает никакой возможности сослаться на объект, в котором хранятся локальные переменные. Истинная природа объектов, в которых хранятся локальные переменные, зависит от конкретной реализации и не должна заботить нас. Однако сам факт наличия объектов с локальными переменными имеет большое значение, и эта тема будет рассматриваться в следующем разделе.

3.10.3 Цепочки областей видимости

JavaScript - это язык программирования с лексической областью видимости: область видимости переменной распространяется на строки с исходным программным кодом, для которых определена переменная. Глобальные переменные определены для всей программы в целом. Локальные переменные определены для всей функции, в которой они объявлены, а также для любых функций, вложенных в эту функцию.

Если считать локальные переменные свойствами некоторого объекта, зависящего от реализации, то появляется возможность взглянуть на области видимости переменных с другой стороны. Каждый фрагмент программного кода на JavaScript (глобальный программный код или тело функции) имеет цепочку областей видимости, ассоциированную с ним. Эта цепочка областей видимости представляет собой список, или цепочку объектов, определяющих переменные, которые находятся «в области видимости» данного фрагмента программного кода. Когда интерпретатору требуется отыскать значение переменной x (этот процесс называется разрешением переменной), он начинает поиск с первого объекта в цепочке. Если этот объект имеет свойство с именем x, используется значение этого свойства. Если первый объект не имеет свойства с именем x, интерпретатор JavaScript продолжает поиск в следующем объекте в цепочке. Если второй объект не имеет свойства с именем x, интерпретатор переходит к следующему объекту и т. д. Если ни один из объектов в цепочке областей видимости не имеет свойства с именем x, то интерпретатор считает, что переменная x находится вне области видимости данного программного кода и возбуждает ошибку ReferenceError.

Поделиться:
Популярные книги

Воронцов. Перезагрузка

Тарасов Ник
1. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Воронцов. Перезагрузка

Бродяга. Книга вторая

Первухин Андрей Евгеньевич
2. Бродяга
Фантастика:
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Бродяга. Книга вторая

На границе империй. Том 10. Часть 2

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Убивая маску

Метельский Николай Александрович
13. Унесенный ветром
Фантастика:
боевая фантастика
5.75
рейтинг книги
Убивая маску

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Проводник

Кораблев Родион
2. Другая сторона
Фантастика:
боевая фантастика
рпг
7.41
рейтинг книги
Проводник

Воспоминания о Корнее Чуковском

Коллектив авторов
Документальная литература:
биографии и мемуары
6.25
рейтинг книги
Воспоминания о Корнее Чуковском

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Геном хищника. Книга шестая

Гарцевич Евгений Александрович
6. Я - Легенда!
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Геном хищника. Книга шестая

Личный аптекарь императора. Том 3

Карелин Сергей Витальевич
3. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Личный аптекарь императора. Том 3