简单来说:JS闭包就是不需要传参,调用外部函数就叫做闭包。
复杂来将:闭包是指某种程序语言中的代码块允许一级函数存在并且在一级函数中所定义的自由变量能不被释放,直到一级函数被释放前,一级函数外也能应用这些未释放的自由变量。
简化一下:闭包,其实就是指程序语言中能让代码调用已运行的函数中所定义的局部变量。
我们来举个例子:
var abc = function (y) {
var x = y;
return function () {
alert(x+++','+y--);
}
}(5);
abc(); //5,5
abc(); //6.4
abc(); //7,3
abc(x); //报错,x未定义
可以很清晰的看到,在外部成功调用了函数内部的局部变量。那么问题来了,这些局部变量难道会一直存放在内存中吗?什么时候会销毁呢?在这个function对象被销毁的时候。
如果在一个外部函数中再定义一个内部函数,即函数嵌套函数,那么内部函数也可以访问外部函数中的变量:
var foo = function (x) {
var temp = 10;
function bar(y) {
alert((temp--) + x + y);
}
bar(10);
}
foo(5); //25
foo(5); //25
foo(5); //25
如上代码所示,尽管bar 能访问函数外部的变量 temp,同时也能访问foo的参数,但这并不是一个闭包的实例。
正确的闭包示例如下:
function foo(x) {
var temp = 10;
return function (y) {
alert((temp--) + x + y);
}
}
var bar = foo(2); //bar现在是闭包了
bar(10); //22
bar(10); //21
bar(10); //20
由此我们可以得出闭包的前提是:需要将内部函数作为外部函数的返回值返回
要实现闭包的话,需要将内部函数作为外部函数的返回值返回,内部函数在返回前,会将所有已访问过的外部函数中的变量在内存中锁定,也就是说,这些变量将常驻
bar
的内存中,不会被垃圾回收器回收,如下:匿名函数形式:
alert((function(x,y){return x+y;})(2,3));// "5"
alert((new Function("x","y","return x*y;"))(2,3));// "6"
匿名函数中的每一对小括号,都有一个返回值,当我们用小括号把一个匿名函数括起来的时候,其实他最后返回的是一个Function对象。
因此,小括号加上匿名函数,就如同我们取得了匿名函数的引用位置,所以在引用变量后面加上实体参数,就如同有名字的函数被调用。
闭包的好处:
不增加额外的全局变量,
执行过程中所有变量都是在匿名函数内部。
不增加额外的全局变量,
执行过程中所有变量都是在匿名函数内部。