讲闭包之前,我们得先理解什么是匿名函数?
我们普通的函数都是这样写的:
Function box(){return 'Lishaoran';}
顾名思义,匿名函数就是没有函数名的函数,如下:
Function(){return 'Lishaoran';}
而匿名函数如果单独运行的话是会报错的,要想不让匿名函数报错可以把它赋给一个变量,如下:
Var box=function(){return 'Lishaoran';};
Alert(box());
也可以让匿名函数自我执行,如下:
(function(){alert('Lishaoran');})();
还可以把匿名函数放到函数里面,如下:
Function box (){ return function(){return 'Lishaoran';}}
Alert(box()());
那么闭包就是最后一种:把匿名函数放到一个函数里面。
具体的官方解释为:闭包是指有权访问另一个函数作用域中的变量的函数。
闭包的常见的方式为:在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
例如:
Function box(){
Var age=100;
Return function(){
Return age;
};
}
Alert(box()());
(一)
闭包有一个优点,同时也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量(使用全局变量不安全,会导致应用程序不可预测性,所以应避免使用。)
这么说可能优点官方,咱们用例子来解释一下:
我们要实现累加,一般都会设置一个全局变量来设置初始值,并得到累加以后的值,如下:
Var age=10;//全局变量
Function Box(){
Age++;//调用全局变量进行累加
}
Box();//执行box函数
Alert(age);//输出累加结果
如果我们换成局部变量,把var age=10放到函数里面的话,就不能实现累加,程序如下:
Function Box(){
Var age=10;/局部变量
Age++;
Return age;
}
Alert(box());
Alert(box());
运行后显示两个11,而不是11,12.
但是如果有了闭包,我们就可以用局部变量来实现累加,从而避免使用全局变量:
Function box(){
Var age=10;//局部变量
Return function(){
Age++;
Return age;
}
}
Var b = box();
Alert(b());
Alert(b());
运行后就可以显示累加:11,12。
注意:在闭包中使用this对象的话,this在运行时是指向window的,而不是指向这个对象的。
(二)
在Javascript中是没有块级作用域的(也就是如果你连续生命多个同一变量,js是不会提醒你声明了同一个变量的,它会对后边声明的视而不见),而使用闭包可以模仿块级作用域从而避免这一问题:
Function box(){
(function(){
For(var i=0;i<5;i++){
}
})();
Alert(i);//运行后报错,因为一出来匿名函数的作用域就把变量i销毁了
}
使用了块级作用域后,匿名函数中定义的任何变量都会在执行结束时被销毁。这样当你在其他的地方声明一个同一名字的变量的时候就不会发生覆盖现象,也不会担心搞乱全局作用域。
(三)
JavaScript没有私有属性的概念,所有的对象属性都是公有的,不过却有一个私有变量(不能再函数外部访问的变量)的概念。而我们可以通过闭包访问这些私有变量,利用这一点可以创建用于访问私有变量的公有方法:
function Box(){
var age=100;//声明私有变量
function run{ //声明私有函数
Return '运行中……';
}
this.get=function(){ //对外公有的特权方法
Return age+run();
};
}
外部调用:
var box= new Box();
alert (box.get());
总结:
这一部分还有包括静态私有变量和模块模式这两个部分,我自己认为理解是挺简单的,但是只有勇于实际才有意义,这里就不做详解了,等用到了再仔细区分!咱们主要理解的是闭包:也就是一般函数中有一个函数,不过这一般函数里面的函数却没有函数名称!