一句话描述闭包
一个持有外部环境变量的函数就是闭包
一个简单的闭包例子
function fun(){
var a = 10;//fun函数作用域内部的变量
return ()=>{
return a;//在此可以访问到fun函数作用域的a
}
}
var geta = fun();
var a = geta();
console.log(a);//通过闭包我们就可以在fun函数外部访问到fun函数内部作用域的变量
闭包的使用场景
- 使用场景一:给对象设置私有变量并且利用特权方法去访问私有属性
function Fun(){
var name = 'tom';
this.getName = function (){
return name;
}
}
var fun = new Fun();
console.log(fun.name);//输出undefined,在外部无法直接访问name
console.log(fun.getName());//可以通过特定方法去访问
- 使用场景二:采用函数引用方式的
setTimeout
调用
setTimeout
:接收两个参数,第一个参数可以是一段js代码,亦可以是一个函数,第二个参数是我们延迟执行第一个参数的时间(实际上不是延迟执行,而是延迟加入执行队列),在此我们要讨论的情况是第一个参数是一个函数的情况,我们传入的参数实际上是函数对象的引用,那这时候就不能向函数传参了,那么闭包就派上用场了
function fun(num){
var age = num;
return function(){
console.log(age);
}
}
var getAge = fun(200);//传入需要的参数,得到函数(闭包)的引用
var age = setTimeout(getAge,1000);//正确输出
- 使用场景三:封装相关功能集
一个内联执行的函数表达式返回了内部函数对象的一个引用。并且分配了一个全局变量,让它可以被作为一个全局函数来调用。而缓冲数组作为一个局部变量被定义在外部函数表达式中。它没有被扩展到全局命名空间中,并且无论函数什么时候使用它都不需要被再次创建。
var getImgInPositionedDivHtml = (function () {
var buffAr = [
'<div id="',
'', //index 1, DIV ID attribute
'" style="position:absolute;top:',
'', //index 3, DIV top position
'px;left:',
'', //index 5, DIV left position
'px;width:',
'', //index 7, DIV width
'px;height:',
'', //index 9, DIV height
'px;overflow:hidden;\"><img src=\"',
'', //index 11, IMG URL
'\" width=\"',
'', //index 13, IMG width
'\" height=\"',
'', //index 15, IMG height
'\" alt=\"',
'', //index 17, IMG alt text
'\"><\/div>'
];
return (function (url, id, width, height, top, left, altText) {
buffAr[1] = id;
buffAr[3] = top;
buffAr[5] = left;
buffAr[13] = (buffAr[7] = width);
buffAr[15] = (buffAr[9] = height);
buffAr[11] = url;
buffAr[17] = altText;
return buffAr.join('');
});
})();