闭包
例:
sum是函数作用域里面的变量,也称局部变量,外面没有办法直接访问这个局部变量,除非把sum最为返回值返回出去,外面才可以访问sum。
function add(){
var sum = 0;
for ( var i = 0 ;i<;i++){
sum = sum + arguments[i];
}
return sum;
}
既然是在函数中,可以把一个变量返回出去,那么自然也可以把一个函数返回出去。(3)
这个例子就是在函数里嵌套了另外一个函数(1),把一个函数返回出去。
function test(){
return function(){
}
}
函数作用域可嵌套,所以里面的函数作用域可以访问外面函数作用域中的变量。
function test(){
var a = 0;
return function(){
(a);
}
}
test里定义了一个局部变量a,变量a属于test函数的函数作用域,最后返回的函数也属于test函数作用域,这个function(匿名函数)内部就有权限访问外部作用域。(2)
也就是说,变量a可以被function访问到。因为test函数返回的结果是一个函数,函数不去调用就不会执行里面的代码,所以如果需要执行内部函数的函数体,就必须要:
test()();
第一个小括号是调用test函数,这个函数定义了局部变量a,还返回一个内部函数。
因此第一次调用结果就是返回一个内部函数。
第二个括号才会调用内部函数。
产生闭包的条件:1.在函数内部也有一个函数(test函数里还有一个函数function)
2.函数内部的函数里面用到了外部函数的局部变量
(test函数有个局部变量a,且被内部函数使用了 )
3.外部函数把内部函数作为返回值return 出去了
调用一个函数,其里面的局部变量会在函数调用结束后销毁,也就是我们在全局作用域里无法访问函数局部变量的 原因。但是如果使用闭包,那么就会让这个局部变量不随着原函数的销毁而销毁,是继续存在的。
function test(){
var a = 0;
return function( increment ){
a = a + increment;
(a);
}
}
// 先获取这个内部函数
var inner = test();
//第一次调用内部函数
inner(1);
//第二次调用内部函数
inner(1);
//第三次调用内部函数
inner(1);
代码执行结果分别为:1、2、3
这样就可以证明在每次调用内部函数的时候,里面访问的都是同一个变量a了。这种写法就相当于在全局作用域里面定义了一个变量a,然后在函数中操作全局变量。但是用这样的形式操作,也就是利用闭包 操作可以减少很多不必要的全局变量。全局作用域是一块公共区域,如果为了某个单一的功能而定义一个全局变量,则会导致全局变量过多,代码就变得一团糟了。因此在这种情况下,还是要优先考虑使用闭包。
自执行函数
语法:(定义一个没有名字的函数)();
例:
(
function(){
(123);
}
)();
自执行函数,就是在定义之后就立刻执行的函数,一般是没有名字的。因为自执行函数没有名字,所以他虽然会被立即执行,但它只会被执行一次。
自执行函数和闭包配合使用:
function test(){
var a = 0;
return function( increment ){
a = a + increment;
(a);
}
}
(这个闭包例子中,真正想得到的是test函数里面的内部函数,所以对test函数并不是很在意,则可以在这个情况下使用自执行函数获取内部函数)
var inner = (function (){
var a = 0;
return function( increment ){
a = a + increment;
(a);
}
}) ();
inner(2);
inner(2);
inner(2);
这样就可以直接得到闭包环境下的内部函数,外部函数只是为了产生闭包环境而临时定义的函数。