JavaScript 闭包
闭包可以定义为JavaScript中的一个特性,即内部函数可以访问外部函数的变量。在JavaScript中,每次创建函数时都会创建一个闭包。 JavaScript 中,闭包具有以下三个作用域链。
- 访问自己的作用域。
- 访问外部函数的变量。
- 访问全局变量。
让我们通过一个示例来理解闭包。
示例1
<!DOCTYPE html>
<html>
<head>
<script>
function fun()
{
var a = 4; // 'a' is the local variable, created by the fun()
function innerfun() // the innerfun() is the inner function, or a closure
{
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() 的主体被返回并存储在变量 输出 中,这是由于语句 return innerfun 。内部函数不会被执行,而只使用 return 语句;只有在后面跟随大括号 () 时才会执行。 在输出中,代码将显示在父函数中定义的变量’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 的乘积。在程序中,输出是闭包。 现在,有一个在循环中的闭包的另一个示例。
示例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中稍难理解的概念之一,但是尝试在不同的场景中练习闭包,比如用于创建回调函数、getters和setters等。