САЙТ ДЛЯ ВЕБ РАЗРАБОТЧИКОВ НА РУССКОМ ЯЗЫКЕ
×

JS Учебник

JS Главная JS Введение JS Установка JS Вывод JS Синтаксис JS Заявления JS Комментарии JS Переменные JS Операторы JS Арифметика JS Присваивания JS Типы данных JS Функции JS Объекты JS Область JS События JS Строки JS Методы строк JS Числа JS Методы чисел JS Массивы JS Методы массива JS Сортировка массива JS Итерация массива JS Даты JS Формат даты JS Метод получения дат JS Методы набора... JS Математические... JS Случайные числа JS Булевы JS Сравнение... JS Заявления if...else JS Заявление switch JS Цикл for JS Цикл while JS Заявление break... JS Преобразование... JS Битовые... JS Регулярные выражения JS Ошибки JS Отладчик JS Подъемный JS Строгий JS Ключевое слово this JS Руководство стиля JS Практика JS Распространенные ошибки JS Эффективность JS Зарезервированные слова JS Версии JS Версия ES5 JS Версия ES6 JS JSON

JS Формы

JS Формы JS Формы API

JS Объекты

Определение объекта Свойства объекта Методы объекта Доступ к объекту Конструкторы объекта Прототипы объекта Объект ECMAScript 5

JS Функции

Определение функции Параметры функции Вызов Функции Вызвать Функцию Применение функции Закрытие Функции

JS HTML DOM

DOM Введение DOM Методы DOM Документы DOM Элементы DOM HTML DOM CSS DOM Анимация DOM События DOM Слушатель события DOM Навигация DOM Узлы DOM Коллекции DOM Список узлов

JS Браузера BOM

JS Окно JS Экран JS Местоположение JS История JS Навигатор JS Всплывающее окна JS Синхронизация JS Cookies

JS AJAX

AJAX Введение AJAX XMLHttp AJAX Запрос AJAX Ответ AJAX XML Файл AJAX PHP AJAX ASP AJAX База данных AJAX Приложения AJAX Примеры

JS JSON

JSON Введение JSON Синтаксис JSON или XML JSON Типы данных JSON Парсинг JSON Строки JSON Объекты JSON Массивы JSON PHP JSON HTML JSON JSONP



JavaScript Закрытие функции



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

Глобальные переменные могут быть сделаны локальными (частными) с закрытиями.


Глобальные переменные

Функция function может получить доступ ко всем переменным, определена внутри функции, например:

Пример

function myFunction() {
  var a = 4;
  return a * a;
}
Попробуйте сами »

Но функция function может также, получить доступ к переменным, определена вне функции, например:

Пример

var a = 4;
function myFunction() {
  return a * a;
}
Попробуйте сами »

В последнем примере a - это глобальная переменная.

На веб странице глобальные переменные принадлежат объекту window.

Глобальные переменные могут использоваться (и изменяться) всеми скриптами на странице и (в window).

В первом примере a - это локальная переменная.

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

Глобальные и локальные переменные с одинаковым именем - это разные переменные. Изменение одногой не изменяет другую.

Переменные, созданные без ключевого слова объявления (var, let, или const), всегда являются глобальными, даже если они созданы внутри функции.



Долговечность переменной

Глобальные переменные живут столько, сколько живет ваше приложение (ваше окно / ваша веб страница).

Локальные переменные имеют короткую жизнь. Они создаются при вызове функции и удаляются после ее завершения.


Встречная дилемма

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

Для увеличения счетчика можно использовать глобальную переменную и функцию function:

Пример

// Инициировать счетчик
var counter = 0;

// Функция для увеличения счетчика
function add() {
  counter += 1;
}

// Вызвать add() 3 раза
add();
add();
add();

// счетчик не должен быть 3
Попробуйте сами »

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

Счетчик должен быть локальным для функции add(), чтобы предотвратить изменение его другим кодом:

Пример

// Инициировать счетчик
var counter = 0;

// Функция для увеличения счетчика
function add() {
  var counter = 0;
  counter += 1;
}

// Вызвать add() 3 раза
add();
add();
add();

//Счетчик теперь должен быть 3. Но это 0
Попробуйте сами »

Это не сработало, потому что мы показываем глобальный счетчик вместо локального счетчика.

Мы можем удалить глобальный счетчик и получить доступ к локальному счетчику, позволив функции вернуть его:

Пример

// Функция для увеличения счетчика
function add() {
  var counter = 0;
  counter += 1;
  return counter;
}

// Вызвать add() 3 раза
add();
add();
add();

//Счетчик теперь должен быть 3. Но это 1.
Попробуйте сами »

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

Внутренняя функция JavaScript может решить эту проблему.


JavaScript вложенные функции

Все функции имеют доступ к глобальной области видимости.

На самом деле, в JavaScript все функции имеют доступ к области "выше" их.

JavaScript поддерживает вложенные функции. Вложенные функции имеют доступ к области "выше".

В этом примере внутренняя функция plus() имеет доступ к переменной counter в родительской функции:

Пример

function add() {
  var counter = 0;
  function plus() {counter += 1;}
  plus();   
  return counter;
}
Попробуйте сами »

Это могло бы решить дилемму счетчика, если бы мы могли добраться до функции plus() извне.

Нам также нужно найти способ выполнить counter = 0 только один раз.

Нам нужно покончить с этим.


JavaScript закрытие

Помните функции самовозбуждения? Что делает эта функция?

Пример

var add = (function () {
  var counter = 0;
  return function () {counter += 1; return counter}
})();

add();
add();
add();

// счетчик теперь 3
Попробуйте сами »

Объясненный пример

Переменной add присваивается возвращаемое значение самопроизвольной функции.

Функция самовозбуждения запускается только один раз. Она устанавливает счетчик в ноль (0) и возвращает выражение функции.

Таким образом, add становится функцией. "Замечательная" часть заключается в том, что он может получить доступ к счетчику в родительской области.

Это называется закрытием JavaScript. Это позволяет функции иметь "собственные" переменные.

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

Закрытие - это функция, имеющая доступ к родительской области, даже после закрытия родительской функции.