闭包 :相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)
1. 函数作为返回值 。
var a = [1,2,3,4,5]
var fun = function(arr)
{
var sum = function()
{
var s = 0;
for(var i of arr)
{
s = s + i;
}
return s;
}
return sum;
}
var f = fun(a)
alert(f())//15
每次调用都会返回一个新的函数,即使传入相同的参数。
2. 返回的函数并没有立刻执行,而是直到调用了
f()
才执行。var fun1=function()
{
var arr = [],i;
for(i=1;i<4;i++)
{
arr.push(function()
{return i*i;})
}
return arr;
}
var ar = fun1();
f1 = ar[0];
f2 = ar[1];
f3 = ar[2];
alert(f1()) //16
alert(f2()) //16
alert(f3())//16
因为函数最开始没有执行,当执行的时候i的值已经是4了,这三个函数都根据i的引用得到了16。解决办法 方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变。看下面
var fun1=function()
{
var arr = [],i;
for(i=1;i<4;i++)
{
arr.push((function(n)
{
return function()
{return n*n;}
})(i));//创建一个函数并立即执行
}
return arr;
}
var ar = fun1();
f1 = ar[0];
f2 = ar[1];
f3 = ar[2];
alert(f1()) //1
alert(f2()) //4
alert(f3()) //9
一个立即执行的匿名函数:
(function (x) {
return x * x;
})(3);
3.封装一个私有变量
var fun2 = function(init)
{
var x = init||0;
return {
incou:function () {
x = x+1;
return x;
}
}
}
var p = fun2()
alert(p.incou()) //1
alert(p.incou()) //2
var pe = fun2(10)
alert(pe.incou()) //11
alert(pe.incou())//12
闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
4. 闭包把多参数的函数变成单参数的函数。
function fun3(x)
{
function fun(n)
{
return Math.pow(n,x)
}
return fun;
}
var pow2 = fun3(2)
var pow3 = fun3(3)
alert(pow2(5)) //25
alert(pow3(5)) //125