到目前为止唯一一篇使用大标题的博客
好久之前就打算写个关于闭包的文章,做了几个关于闭包的题目之后发现自己还是没有完全弄明白它,翻阅了各种资料后,整理思路在西安这个炎热地将近40度并且小区停电不能回家留在公司开着空调避暑的日子写下这篇仅供参考的文章。
闭包的个人理解定义:A function what returns a function;表现上体现为:能够读取其他函数内部变量的函数
学习闭包前,有一个内容必须要了解,那就是“变量的作用域”。
JS中的变量作用域只有两种:全局作用域和函数作用域,
*区别于其它语言,它是没有块作用域的(if,for中语句包裹的变量,如下)
if(true){
var test = 1;
}
test++;//test虽然被定义到到了if条件中,但是还是可以正常访问到
console.log(test);//返回 2
上述栗子可以正常访问到test值,说明JS中是没有块级作用域的,否则不能访问到test的值。有人可能会说,if(true)
和不写有什么区别!这不是糊弄人嘛!我只能说“好问题!”再看下面的栗子:
if(false){
var test = 1;
}
test++;
console.log(test);//返回 NaN
现在if语句没有执行吧,为什么test++会返回NaN,按理说对一个没有定义的变量直接运算是会报错的,就像下面这样:
test++;
console.log(test);//Uncaught ReferenceError: test is not defined
那if没执行岂不是就没有定义test,就跟上面的栗子一样了,但是为啥却没报错?带着疑问我们再试!
var test;
test++;
console.log(test);//返回 NaN
写到这里你应该就明白了吧,JS由于没有块级作用域,JS解析的时候也就会无视if语句,又因为JS变量声明提升这一特点,就算if语句不满足条件没有执行,test也是被定义了的。如下图
执行test++之前,test是undefined(就算if语句不成立)
对undefined执行++操作返回值为NaN
一不小心又扯远了,回归正题,JS中,函数内部是可以访问函数外部的全局作用域变量的,但是函数外部访问不到函数内部的函数作用域变量。闭包囊,这个bitch就偏偏打破了这个特性,使得变通之后函数外部也能访问函数内部的变量。
举个例子:
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
如上图,函数外部是可以访问到其内部变量n的囊。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包的用途
俗话说的好,因材施教,要讨论闭包的用途,就要先弄明白它的特性。
闭包最大的两个特性:
一:可以读取函数内部的变量;
二:让这些变量的值始终保持在内存中;为啥囊?当内部函数在定义它的作用域 的外部被引用时,就创建了该内部函数的闭包 。如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被释放,因为闭包需要它们。