闭包的用途
闭包必读:https://github.com/mqyqingfeng/Blog/issues/9
练习题
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}
data[0]();
data[1]();
data[2]();
var data = []; for (var i = 0; i < 3; i++) { data[i] = (function () { return function() { console.log(i); } })(i); } data[0](); data[1](); data[2]();
var data = []; for (var i = 0; i < 3; i++) { data[i] = (function (i) { return function(){ console.log(i); } })(i); } data[0](); data[1](); data[2]();
var data = []; for (let i = 0; i < 3; i++) { data[i] = function () { console.log(i); }; } data[0](); data[1](); data[2]();
答案: 3,3,3
3,3,3
0,1,2
0,1,2
转载自:https://www.cnblogs.com/yunfeifei/p/4019504.html
什么是闭包?
MDN对闭包的解释如下:
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
function outer() {
const a = 10;
function inner() {
return a;
}
return inner;
}
var innerFunc = outer();
console.log(innerFunc()); // 输出 10
我们执行outer返回的inner函数,inner函数内部引用了outer函数中的变量a. outer函数执行结束后,变量a不会被销毁,而是继续留在内存中。
闭包在前端常用的使用场景:
- 函数句柄
- 回调函数
- 函数式声明
1、结果缓存
我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值;如果找到了,直接返回查找到的值即可。
之所以闭包可以做到这一点,使因为它不会释放外部活动对象的引用,从而函数内部的值可以得以保留。
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("input");
2.封装
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