本质:函数(内嵌函数)
闭包就是能访问到外部函数中变量的内部函数
定义:一个可以访问自由变量的函数
function a(){
var x='111';
//闭包函数
function b(){
console.log(x);//
}
}
原理:依赖于作用域链
引用自由变量的过程中将自由变量注入到自身的作用域
闭包构成要点
- 闭包必须有函数的嵌套
- 内部函数必须要访问函数外部的变量或者参数(能够访问自由变量)
- 被访问的变量或者参数永久保存在系统内存当中
4 .必须将内部函数作为返回值返回
使用场景
-
访问一个函数内部变量,函数体外使用一个函数体内部的变量
function fn(){
var userName='admin';
function fn2() {
return userName;//保存在内存当中
}
}
//想拿到userName
var result=fn();
console.log(result)//result==fn2()
var value=result();//调用fn2
console.log(value);//admin
循环取值(输出每一次循环的当前值)
/*点击每一个li,背景颜色变成粉色,同时打印出每一个li的索引*/
//循环赋值 绑定事件的闭包
<ul>
<li><a href='#'>111</a></li>
<li><a href='#'>222</a></li>
<li><a href='#'>333</a></li>
<li><a href='#'>444</a></li>
<li><a href='#'>555</a></li>
</ul>
<script>
var liList=document.getElememtsByTagName('li');
for(var i=0;i<liList.length;i++){
//立即执行函数(自调函数)
(function(num){
//闭包 num变量就是闭包变量,不会被销毁
liList[i].onclick=function(){
this.style.background='pink';
console.log(num);
}
})(i)
}
}
</script>
参数注入
//截取文件扩展名
function fn(str,fn1){
//第一个参数str是需要截取的文件,第二个参数是一个函数
//字符串截取
//获取截取文件最后一次出现.的索引位
var index=str.lastIndex0f('.');
//.的索引位加一,截取的就是.后面的扩展名
var extName=str.substr(index+1);
//代理匿名函数
fn1(extName);
}
//调用fn传参 传字符串和函数
fn('erefewgtgtrg.txt',function(v,k){
console.log(v,k);
})
闭包的优点
1、永久保存数据
2、避免全局污染
3、变量的私有化
闭包的缺点
1、由于变量无法回收,使用频繁,内存损耗太大
2、内存泄漏的风险
如何销毁闭包?
function fn(){
var userName='zhuyin';
//闭包
function val(){
return userName; //保存在内存当中
}
return val;//返回函数
}
var result=fn();//调用fn 此时 result==val()
result=null;//让内存函数val()=null,此时闭包被销毁