В този урок ще научите за затварянето на JavaScript с помощта на примери.
Преди да научите за затварянията, трябва да разберете две понятия:
- Вложена функция
- Връщане на функция
JavaScript вложена функция
В JavaScript функция може да съдържа и друга функция. Това се нарича вложена функция. Например,
// nested function example // outer function function greet(name) ( // inner function function displayName() ( console.log('Hi' + ' ' + name); ) // calling inner function displayName(); ) // calling outer function greet('John'); // Hi John
В горната програма greet()
функцията съдържа displayName()
функцията вътре в нея.
Връщане на функция
В JavaScript можете също да върнете функция в рамките на функция. Например,
function greet(name) ( function displayName() ( console.log('Hi' + ' ' + name); ) // returning a function return displayName; ) const g1 = greet('John'); console.log(g1); // returns the function definition g1(); // calling the function
Изход
функция displayName () (console.log ('Hi' + '' + name);) Здравей Джон
В горната програма greet()
функцията връща displayName
дефиницията на функцията.
Тук върнатата дефиниция на функцията се присвоява на променливата g1. Когато отпечатвате g1 с помощта console.log(g1)
, ще получите дефиницията на функцията.
За да извикаме функцията, съхранена в променливата g1, използваме g1()
със скоби.
Затваряне на JavaScript
В JavaScript затварянето осигурява достъп до външния обхват на функция от вътрешната функция, дори след като външната функция се затвори. Например,
// javascript closure example // outer function function greet() ( // variable defined outside the inner function let name = 'John'; // inner function function displayName() ( // accessing name variable return 'Hi' + ' ' + name; ) return displayName; ) const g1 = greet(); console.log(g1); // returns the function definition console.log(g1()); // returns the value
Изход
функция displayName () (// достъп до променлива за връщане 'Hi' + '' + name;) Здравей Джон
В горния пример, когато greet()
е извикана функция, тя връща дефиницията на функцията на displayName
.
Тук g1
е препратка към displayName()
функцията.
Когато g1()
бъде извикан, той все още има достъп до greet()
функцията.
Когато стартираме console.log(g1)
, той връща дефиницията на функцията.
Концепцията за затваряне съществува за други езици за програмиране като Python, Swift, Ruby и др.
Нека да разгледаме друг пример.
// closure example function calculate(x) ( function multiply(y) ( return x * y; ) return multiply; ) const multiply3 = calculate(3); const multiply4 = calculate(4); console.log(multiply3); // returns calculate function definition console.log(multiply3()); // NaN console.log(multiply3(6)); // 18 console.log(multiply4(2)); // 8
В горната програма calculate()
функцията приема един аргумент x
и връща дефиницията на multiply()
функцията на функцията. Най multiply()
функцията приема единствен аргумент y
и се връща x * y
.
Както multiply3
и multiply4
са за затваряне.
В calculate()
функция се нарича преминаване параметър x
. Когато multiply3
и multiply4
са извикани, multipy()
функцията има достъп до предадения аргумент x на външната calculate()
функция.
Поверителност на данните
Затварянето на JavaScript помага в поверителността на данните на програмата. Например,
let a = 0; function sum() ( function increaseSum() ( // the value of a is increased by 1 return a = a + 1; ) return increaseSum; ) const x = sum(); console.log(x()); // 1 console.log(x()); // 2 console.log(x()); // 3 a = a + 1; console.log(a); // 4
В горния пример sum()
функцията връща дефиницията на increaseSum()
функцията на функцията.
Променливата се увеличава във increaseSum()
функцията. Стойността на променливата обаче може да бъде променена и извън функцията. В този случай a = a + 1;
променя стойността на променливата извън функцията.
Сега, ако искате променливата да се увеличава само във функцията, можете да използвате затваряне. Например,
function sum() ( let a = 0; function increaseSum() ( // the value of a is increased by 1 return a = a + 1; ) return increaseSum; ) let x = sum(); let a = 5; console.log(x()); // 1 console.log(x()); // 2 console.log(a); // 5
В горния пример sum()
функцията задава стойността на a на 0 и връща increaseSum()
функцията.
Поради затварянето, въпреки че sum()
вече е изпълнено, increaseSum()
все още има достъп до a и може да добави 1 към всеки път, когато x()
се извика.
И променливата е частна за sum()
функцията. Това означава, че променливата може да бъде достъпна само във sum()
функцията.
Дори ако го декларирате a
и използвате, това не засяга a
променливата във sum()
функцията.
Забележка : Обикновено затварянията се използват за поверителност на данните.