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

К глобальной переменной можно обращаться и манипулировать в любом месте программы, тогда как к локальной переменной можно обращаться и манипулировать только той функцией, в которой они объявлены.

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

Давайте посмотрим, что произойдет, если вы попытаетесь достичь этого с помощью глобальной переменной:

// Глобальная переменная
var counter  = 0;

// Функция, предназначенная для манипулирования переменной 'counter'
function makeCounter() {
    return counter += 1;
}

// Вызов функции
makeCounter();
console.log(counter); // Выводит: 1

makeCounter();
console.log(counter); // Выводит: 2

// Попытка манипулировать переменной 'counter' извне
counter = 10;
console.log(counter); // Выводит: 10

Как видно из приведенного выше примера, значение переменной counter можно изменить из любой точки программы, не вызывая функцию makeCounter().

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

function makeCounter() {
    // Локальная переменная
    var counter  = 0;
	
    // Управление переменной 'counter'
    return counter += 1;
}

// Вызов функции
console.log(makeCounter()); // Выводит: 1
console.log(makeCounter()); // Выводит: 1

В этом случае переменной counter нельзя манипулировать извне, поскольку она является локальной для функции makeCounter(), но ее значение также не будет увеличиваться после последующего вызова функции, поскольку каждый раз, когда мы вызываем функцию, она сбрасывает значение переменной counter. «Закрытие» (closure) JavaScript может решить нашу проблему.

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

function makeCounter() {
    var counter = 0;
	
    // Вложенная функция
    function make() {
        counter += 1;
        return counter;
    }
    return make;
}

/* Выполняем функцию makeCounter() и сохраняем возвращаемое значение в переменной myCounter */
var myCounter = makeCounter();

console.log(myCounter()); // Выводит: 1
console.log(myCounter()); // Выводит: 2

Как видно из приведенного выше примера, внутренняя функция make() возвращает переменную во внешнюю функцию makeCounter(). Таким образом, значением myCounter является значение функции make(). В JavaScript функции могут быть назначены переменным, переданы в качестве аргументов другим функциям, могут быть вложены в другие функции и т.д.

Вы также заметите, что внутренняя функция make() все еще может получить доступ к значению переменной counter, определенной во внешней функции, даже если функция makeCounter() уже завершила выполнение. Это происходит потому, что замыкающие функции в JavaScript хранят ссылки на их внешние переменные и могут получать доступ и обновлять их значения.

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

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

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

// Выражение анонимной функции
var myCounter = (function() {
    var counter = 0;
	
    // Вложенная анонимная функция
    return function() {
        counter += 1;
        return counter;
    }
})();

console.log(myCounter()); // Выводит: 1
console.log(myCounter()); // Выводит: 2

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

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

Создание функций Getter и Setter

Здесь мы создадим переменную secret и защитим ее от прямого манипулирования извне кода с помощью замыкания. Мы также создадим функции получения и установки для получения и установки его значения.

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

var getValue, setValue;

// Самоисполняющаяся функция
(function() {
    var secret = 0;
    
    // Функция Getter
    getValue = function() {
        return secret;
    };
    
    // Функция Setter
    setValue = function(x) {
        if(typeof x === "number") {
            secret = x;
        }
    };
}());

// Вызов функций
getValue(); // Возвращает: 0
setValue(10);
getValue(); // Возвращает: 10
setValue(null);
getValue(); // Возвращает: 10

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

Похожие посты

Руководство по сортировке массивов в JavaScript

Сортировка — обычная задача при работе с массивами. Она будет использоваться, например, если вы захотите отобразить названия городов или регионов в алфавитном порядке. JavaScript массив (array) имеет встроенный метод sort() для сортировки элементов массива в алфавитном порядке. Следующий пример демонстрирует, как это работает: Реверсирование массива Вы можете использовать метод reverse(), чтобы изменить порядок элементов массива…

Руководство по массивам в JavaScript

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

Руководство по работе с атрибутами DOM в JavaScript

Атрибуты — это специальные слова, используемые внутри начального тега HTML-элемента для управления поведением тега или предоставления дополнительной информации о теге. JavaScript предоставляет несколько методов для добавления, удаления или изменения атрибутов HTML-элемента. В этом разделе мы узнаем об этих методах подробно. Получение значения атрибута элемента Метод getAttribute() используется для получения текущего значения атрибута элемента. Если указанный…

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 5 / 5. Количество оценок: 1

Оценок пока нет. Поставьте оценку первым.