JavaScript教程-JavaScript 闭包

JavaScript 闭包是一种特性,其中内部函数可以访问外部函数的变量。在 JavaScript 中,每次创建函数时都会创建一个闭包。
闭包具有三个作用域链,如下所示:
- 访问自身的作用域。
- 访问外部函数的变量。
- 访问全局变量。
让我们通过一个示例来理解闭包。
示例 1
<!DOCTYPE html>
<html>
<head>
<script>
function fun() {
var a = 4; // 'a' 是由 fun() 创建的局部变量
function innerfun() // innerfun() 是内部函数,也是闭包
{
return a;
}
return innerfun;
}
var output = fun();
document.write(output());
document.write(" ");
document.write(output());
</script>
</head>
<body>
</body>
</html>
输出:
4 4
在上面的程序中,我们有两个函数:fun()
和 innerfun()
。函数 fun()
创建了局部变量 a
和函数 innerfun()
。内部函数 innerfun()
只存在于 fun()
的主体中。内部函数可以访问外部函数的变量,因此函数 innerfun()
可以访问在 fun()
中声明和定义的变量 'a'
。
这是闭包的工作原理,内部函数可以访问全局变量和外部函数变量。
函数 innerfun()
的整个主体被返回并存储在变量 output
中,因为有 return innerfun
语句。内部函数只有在跟着括号 ()
时才会执行。
在输出中,代码将显示在父函数中定义的变量 'a'
的值。
示例 2
<!DOCTYPE html>
<html>
<head>
<script>
function fun(a) {
function innerfun(b) {
return a * b;
}
return innerfun;
}
var output = fun(4);
document.write(output(4));
document.write(" ");
document.write(output(5));
</script>
</head>
<body>
</body>
</html>
输出:
16 20
在上面的程序中,有两个带参数的函数:fun()
和 innerfun()
。函数 fun()
具有参数 a
,而函数 innerfun()
具有参数 b
。函数 fun()
返回一个函数 innerfun()
,该函数接受一个参数并返回 a
和 b
的乘积。在程序中,output
是闭包。
示例 3
<!DOCTYPE html>
<html>
<head>
<script>
function fun() {
function closure(val) {
return function() {
return val;
}
}
var a = [];
var i;
for (i = 0; i < 5; i++) {
a[i] = closure(i);
}
return a;
}
var output = fun();
document.write(output[0]());
document.write(" ");
document.write(output[1]());
document.write(" ");
document.write(output[2]());
document.write(" ");
document.write(output[3]());
document.write(" ");
document.write(output[4]());
</script>
</head>
<body>
</body>
</html>
输出:
0 1 2 3 4
闭包指向变量并存储变量的引用。它们不记住变量的值。在上面的代码中,我们在每次调用中更新了函数 closure()
的参数。因此,我们将在不同的索引处得到变量 i
的不同值。
闭包是 JavaScript 中稍微难以理解的概念之一,但请尝试在不同的场景中练习闭包,例如创建回调函数、创建 getter 和 setter。