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

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

Жанры

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

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

f
была определена в цепочке видимости, где переменная scope связана со значением «local scope». Эта связь остается действовать и при выполнении функции f, независимо от того, откуда был произведен ее вызов. Поэтому последняя строка в примере выше вернет «local scope», а не «global scope». Проще говоря, эта особенность является самой удивительной и мощной чертой замыканий: они сохраняют связь с локальными переменными (и параметрами) внешней функции, где они были определены.

В разделе 8.4.1 был приведен пример функции

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

var uniquelnteger = (function { // Определение и вызов

var counter =0; // Частное значение для функции ниже

return function { return counter++; };

});

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

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

function counter { var n = 0;

return {

count: function { return n++; },

reset: function { n = 0; }

};

}

var c = counter, d = counter; // Создать два счетчика

c.count // => 0

d.count // => 0: они действуют независимо

с.reset // методы reset и count совместно

// используют одну переменную

c.count // => 0: сброс счетчика с

d.count // => 1: не оказывает влияния на счетчик d

Функция

counter
возвращает объект «счетчика». Этот объект имеет два метода:
count,
возвращающий следующее целое число, и
reset,
сбрасывающий счетчик в начальное состояние. В первую очередь следует запомнить, что два метода совместно используют одну и ту же частную переменную n. Во-вторых, каждый вызов функции
counter
создает новую цепочку областей видимости и новую скрытую переменную. То есть, если вызвать функцию
counter
дважды, она вернет два объекта-счетчика с различными скрытыми переменными. Вызов методов
count
и
reset
одного объекта-счетчика не оказывает влияния на другой.

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

counter
является вариацией примера, представленного в разделе 6.6, но здесь для хранения скрытой информации вместо обычного свойства объекта используются замыкания:

function counter(n) { // Аргумент n функции - скрытая переменная

return {

// Метод чтения свойства возвращает и увеличивает переменную счетчика,

get count { return n++; },

// Метод записи в свойство не позволяет уменьшать значение n

set count(m) {

if (m >= n)

n = m;

else throw Error( "значение счетчика нельзя уменьшить");

}

};

}

var с = counter(1000);

с.count // => 1000

с.count // => 1001

с.count = 2000

с.count // => 2000

с.count = 2000 // => Ошибка!

Обратите внимание, что эта версия функции

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

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

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

Жена неверного ректора Полицейской академии

Удалова Юлия
Любовные романы:
любовно-фантастические романы
4.25
рейтинг книги
Жена неверного ректора Полицейской академии

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

За Горизонтом

Вайс Александр
8. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
За Горизонтом

Ключи мира

Кас Маркус
9. Артефактор
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Ключи мира

Чужак из ниоткуда

Евтушенко Алексей Анатольевич
1. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда

Командор космического флота

Борчанинов Геннадий
3. Звезды на погонах
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Командор космического флота

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21

Мы друг друга не выбирали

Кистяева Марина
1. Мы выбираем...
Любовные романы:
остросюжетные любовные романы
прочие любовные романы
современные любовные романы
5.00
рейтинг книги
Мы друг друга не выбирали

Хозяин Теней 5

Петров Максим Николаевич
5. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 5

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

Сапфир Олег
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Кодекс Охотника. Книга XXXIX

Сирийский рубеж 2

Дорин Михаил
6. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 2

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Чехов

Гоблин (MeXXanik)
1. Адвокат Чехов
Фантастика:
фэнтези
боевая фантастика
альтернативная история
5.00
рейтинг книги
Чехов

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3