理解JavaScript闭包?
首先理解变量的作用域
变量的作用域无非两种
- 全局变量 global
- 局部变量 local
tips: 里提到一个小知识
使用var声明的变量,其作用域为该语句所在的函数内,且存在变量提升现象。
使用let声明的变量,其作用域为该语句所在的函数代码块内,不存在变量提升的现象
使用const声明的是常量,在后面出现的代码中不能再修改该常量的值
而JavaScript的语法中,函数内部可以直接读取全局变量
另一方面,函数外部自然无法读取函数内部的局部变量
- 需要注意的是,函数内部声明变量的时候,一定要使用var命令,如果不用的话,你实际上是声明了一个全局变量
function f1(){
n=999;
}
f1();
alert(n); // 999
如何从外部读取局部变量?
由于项目需求,我们可能需要得到函数内的局部变量,但是在正常情况下这是做不到的。所以只能通过变通的方法实现。
在函数的内部再定义一个函数
function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
上面是一个标准的JavaScript特有的 “链式作用域” 结构chain scope) ,子对象会一级一级的向父级对象寻找所有的变量
既然f2可以读取到f1的变量,辣么,只要把f2作为返回值,我们不久可以再外部读取它的内部变量的吗?
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
闭包的概念。
- f2 就是闭包
- 闭包:能读取其他函数内部(局部)变量的函数
- JavaScript中,只有函数内部的子函数能读取到局部变量,所以可以把闭包理解为:定义在函数内部的函数
- 闭包是函数内部以及外部链接的桥梁
闭包的作用?
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中。
function f1(){
var n=999;
nAdd=function(){
n+=1
}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 10000
闭包的运行逻辑(个人理解,并不确定是否正确:路子野)
- function a(){ n = 1; function a1(){ console.log(“hello”)} return a1}
- b = a() c = a() //声明a函数 且赋值a()赋值于b,c变量
- 此时会再次生成两个内存空间存放b,c的闭包函数(a1)
- 由于a’.a1以及a’’.a1的存在也就是b,c的存在所以a’ 以及 a’’ 并不会被gc(辣鸡回收)
- 将内部变量保存在其中
注意
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
调用你的是WHO?