在学习闭包之前,您需要了解两个概念:
- 嵌套函数
- 返回函数
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;
}
let g1 = greet('John');
console.log(g1); // returns the function definition
g1(); // calling the function
输出
function displayName() {
console.log('Hi' + ' ' + name);
}
Hi John
在上面的程序中, greet()
函数返回displayName
函数定义。
在此,将返回的函数定义分配给g1变量。使用console.log(g1)
打印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;
}
let g1 = greet();
console.log(g1); // returns the function definition
console.log(g1()); // returns the value
输出
function displayName() {
// accessing name variable
return 'Hi' + ' ' + name;
}
Hi John
在上面的示例中,当调用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;
}
let multiply3 = calculate(3);
let 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
都是闭包。
称为validate 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;
}
let x = sum();
console.log(x()); // 1
console.log(x()); // 2
console.log(x()); // 3
a = a + 1;
console.log(a); // 4
在上面的例子中, sum()
函数返回的函数定义increaseSum
函数。
a变量在increaseSum()
函数increaseSum()
。但是, a变量的值也可以在函数外部更改。在这种情况下, 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()
函数设置的为0的值,并返回increaseSum
函数。
由于封锁,即使sum()
已经执行, increaseSum()
仍然有访问 ,并可以添加1 到每次x()
被调用。
并且a变量是sum()
函数的私有变量。这意味着a变量只能在sum()
函数内部访问。
即使你宣布a
,并使用它,它不会影响a
中的变量中sum()
函数。
注意 :通常,闭包用于保护数据隐私。