闭包

作用域

1.作用域:用于确定在何处以及如何查找变量的一套规则。

2.词法作用域:词法作用域是定义在词法阶段的作用域,词法作用域是由写代码时将代码和块作用域写在哪里来决定的,因此当词法作用域处理代码是会保持作用域不变。

3.块作用域:指的是变量和函数不仅可以属于所处的作用域,也可以属于某个代码块,常见的块级作用域有with,try/catch,let,const等。

4.函数作用域:属于这个函数的全部变量都可以在整个函数范围内使用及复用。

5.作用域链:查找变量时,先从当前作用域开始查找,如果没找到,就会到父级进行查找,一直到全局作用域,作用域链正是包含这些作用域的列表。

什么是闭包

能够在函数定义的作用域外,访问函数作用域内的局部变量,并且不会污染全局变量。

基于词法作用域链和垃圾回收机制,通过维持函数作用域的引用,让函数作用域可以在当前作用域外进行访问。

闭包的应用

IIFE,立即调用的自执行函数
利用的优势:可立即执行,并且这种机制不会污染全局对象

方法的封装,通过闭包的形式访问变量,避免了全局变量的污染。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var person = function(){  
//变量作用域为函数内部,外部无法访问
var name = "default";

return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();

print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());

得到结果如下:

undefined
default
abruzzi

用来缓存数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var CachedSearchBox = (function(){  
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果结果在缓存中
return cache[dsid];//直接返回缓存中的对象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新缓存
if(count.length > 100){//保正缓存的大小<=100
delete cache[count.shift()];
}
return fsb;
},

clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();

CachedSearchBox.attachSearchBox("input1");

具体使用场景
实现防抖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function debounce(func, wait) {
let timer = null;

return function () {
if (timer) {
clearTimeout(timer);
timer = null;
}

let self = this;
let args = arguments;

timer = setTimeout(function () {
func.apply(self, args);
timer = null;
}, wait);
};
}

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2019-2021 伯温

请我喝杯咖啡吧~