闭包是什么
定义在一个函数内部的函数;一个可以访问另一个函数作用域内的变量的函数闭包作用
可以读取函数内部的变量;让这些变量的值始终保持在内存中;
可以用于创建私有函数或方法。
保护命名空间
避免污染全局变量
实现原理
因为javascript没有块级作用域,因此外部你是怎么用闭包的
1匿名自执行函数:我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。(模仿块级作用域)2实现封装,在person之外的地方无法访问其内部的变量,而通过提供闭包的形式来访问
3 缓存
设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
4在对象中创建私有变量
即时js中没有正式的私有对象属性的概念,但可以使用闭包来实现公有方法,而通过公有方法可以访问在包含作用域中的定义的变量。有权访问私有变量的公有方法叫做特权方法。可以使用构造函数模式、原型模式来实现自定义类型的特权方法,也可以使用模块模式、增强的模块模式来实现单例的特权方法。
把有权访问私有变量和私有函数的公有方法称为特权方法
在循环中直接找到对应元素的索引(事件循环绑定时候)
在某些情况下使用闭包的技术来减少变量实例化次数太多,减少内存消耗
使用闭包的注意点
1) 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } var a = fun(0); a.fun(1); a.fun(2); a.fun(3);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var c = fun(0).fun(1); c.fun(2); c.fun(3);