闭包用来解决什么
js的作用域分两种,全局和局部。我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的变量并且可以获得当前包含当前作用域的外层作用域下的变量,反之则不能,也就是说在外层作用域下无法获取内层作用域下的变量,同样在不同的函数作用域中也是不能相互访问彼此变量的。
那么我们想在一个函数内部也有限权访问另一个函数内部的变量该怎么办呢?闭包就是用来解决这一需求的,闭包的本质就是在一个函数内部创建另一个函数。
闭包的概念
闭包就是定义在函数内部并且能够读取其他函数局部变量的函数。
闭包的三大特点
1、函数嵌套函数
2、内部函数可以访问外部函数的变量
3、参数和变量不会被回收。
闭包的作用
设计私有变量及方法
在js中实现类似java创建类的功能:
(function(){
var name="wangyu";
Person=function (val) {
name=val;
}
Person.prototype.setName=function(val){
name=val;
}
Person.prototype.getName=function () {
return name;
}
})();
var person1=new Person("sj");
alert(this.name)//undefined 因为在function作用域外不能访问
alert(person1.getName());//wangyu
在function里面的name,由于是在function作用域中,所以外部无法访问,但是可以通过创建person对象,调用person的方法,来达到
修改和访问name值的目的,类似于java类中的私有变量,外部无法访问,只能通过类方法访问。
注意:
一般情况下,在函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为fn的返回值被赋值给了fn1,这时候相当于fn1=function(){var n = 0 ... },并且匿名函数内部引用着fn里的变量num,所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次fn1执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题
闭包的好处
1.保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
2.在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
3.匿名自执行函数可以减少内存消耗
闭包的坏处
1.因为闭包会使得函数的变量始终存在与内存中,所以会对内存造成很大的消耗,会造成网页的性能问题。并且在IE中还会造成内存泄漏的问题。
2.因为闭包会使得外部函数的变量始终曝露在内存中,应该注意尽量不要改变外部函数的变量值。
3.其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响