本文对应《JavaScript忍者秘籍》第5章内容。
1.理解闭包
闭包允许函数访问并操作函数外部的变量,只要变量或函数存在于声明函数是的作用域内。
来看一个简单的闭包:
var air='air';
var inTheHouse=()=>console.log('breathe '+air);
inTheHouse();//breathe air
现在我们去美国呼吸香甜的空气:
var breathe;
var sweetAir=()=>{
var air='American air';
breathe=()=>console.log('breathe '+air);
};
sweetAir();
breathe();//breathe American air
乍一看,当breathe()
执行时,air
所在的作用域已经消失,为什么还能访问到内部变量呢?
当在外部函数中声明内部函数时,不仅定义了函数的声明,还创建了一个闭包。闭包包括函数的声明,和函数声明时该作用域中的所有变量。当内部函数执行时,声明时的作用域消失,但通过闭包仍可访问原始的作用域。这样我们就呼吸到了香甜空气了。
存储闭包将影响性能,勿滥用闭包。
2.应用闭包
封装私有变量
原生JavaScript
不支持私有变量。我们可以创建类似其他语言内的私有变量,使他们对外部隐藏。
function Guess(){
var ans=Math.floor(Math.random()*100);
this.ask=(x)=>{
if(x<ans){
return "too small";
}
else if(x>ans){
return "too large";
}
else if(x===ans){
return "right!";
}
else{
return "无可奉告";
}
};
};
ans
在闭包内部可以被ask
访问,在闭包外部不可访问。
回调函数
回调函数指需要在将来不确定的某一时刻异步调用的函数。
通常在回调函数中需要频繁访问外部数据。