本篇文章包懂
什么是闭包
总有人看到闭包就头疼,因为“闭包”二字实在让人搞不懂它的语义。但闭包其实是个很简单的概念:闭包就是一个函数,只不过这个函数有些不一样。至于它哪里不一样呢,可以用一句话总结出来闭包:
闭包就是一个可以访问另一个函数作用域中的变量的函数
因为我们在编程的过程中,有时候会有“想在一个函数内部也可以访问到另一个函数内部的变量”的需求,所以在这种情况下,闭包就应运而生了。
闭包的特性
- 函数嵌套函数
- 函数内部可以引用函数外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
看不懂没关系,先观察以下的代码
一个简单的闭包
function fn1(){
var a = 1;
return function fn2(){ // fn2 就是一个闭包
alert(a);
}
}
var fn = fn1()
alert(a); // 报错:a is not defined
fn(); // 弹出 1
这段代码的逻辑很简单,甚至有人在不知道什么是闭包之前自己就用过闭包。
我们来剖析一下上边的代码:
- 定义一个函数fn1,在函数内定义一个变量 a=1
- 在函数fn1内返回一个 fn2
- 在 fn2 内 调用 fn1 的变量 a
- 定义一个 fn ,把 fn1 的返回值 —— fn2 赋值给 fn
- 此时 fn 就是 fn2 , 执行 fn ,成功弹出 1
通过观察代码我们知道, fn()
其实就是 alert(a)
,那为什么 fn()
可以成功访问到变量 a
,而直接 alert(a)
就不行呢?——当然不行,JavaScript 的变量引用是基于由下到上,由内而外的链式查找的,所以外部是不能访问到函数内定义的变量的。而闭包则替我们完成了这一点,因为闭包遵循链式查找的法则,而且基于它的特性:闭包访问到的参数和变量不会被垃圾回收机制回收,我们就成功的实现了在外部访问函数内部的变量。
读到这里,你已经精通闭包了。
使用闭包的优越性
- 将函数内部变量进行封装,保证内部变量的私有化,外部无法直接访问。
- 避免了命名冲突。
- 将这个变量长期驻扎在内存之中,不会被销毁。(这一点要合理使用,如果过多的使用闭包会造成内存消耗过多)
稍后更新闭包的使用场景,等一个催更...