JS闭包
2020-03-24 本文已影响0人
罂粟1995
闭包,几乎是面试必考。
什么是闭包
一个函数的作用域是定义作用域而非执行作用域。常见的表现形式是函数包含在其他函数之中,能够读取其他函数内部的变量。
每当声明了一个函数,它就产生了一个闭包域,凡是在闭包域内声明的变量或方法,外部无法直接访问,闭包域却可以访问外部的变量或方法。
闭包的应用:数据缓存
如果有一个函数,每次计算的时候会耗费很大的性能,我们就可以利用闭包数据缓存来进行优化。
将函数的计算结果储存在缓存中,当下次计算时,先查看缓存有没有相应的结果值,如果有,取缓存值,如果没有,执行函数,并保存缓存值。记得控制缓存的大小。
代码示例:
var CachedSearchData = (function () {
var cache = {};
var count = [];
return {
getSearchData: function (id) {
if (id in cache) {//如果结果在缓存中
return cache[id];//直接返回缓存中的对象
} else {
//到数据库中查找
//存缓存
cache[id] = id;
if(count.indexOf(id) == -1){
count.push(id);
}
if(count.length > 100){
delete cache[count.shift()];
}
return "not in cache";
}
},
};
})();
console.log(CachedSearchData.getSearchData(77));//输出not in cache
console.log(CachedSearchData.getSearchData(77));//输出77
闭包的应用:匿名自执行函数
有的函数只需要执行一遍,例如UI的初始化;创建一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,这种机制不会污染全局对象。
(function () {
//自执行函数
})();
闭包的应用:实现封装
在某个对象之外无法访问它的内部变量,而是提供闭包的形式来访问。
代码示例:
var person = function() {
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}()
常见面试题:
- 实现一个函数a(),第一次执行时输出1,第二次执行时输出2,第三次执行时输出1,第四次执行时输出2,第五次执行时输出1……如此循环。
var a = (function(){
var temp = 1;
return function () {
console.log(temp);
temp == 1 ? temp = 2 : temp = 1;
}
})();
a() //输出1
a() //输出2
a() //输出1
a() //输出2
- 实现循环中的延时打印。
for(var i = 1; i < 4; i++) {
setTimeout(
(function(i){
return function () {
console.log(i);
}
})(i),
300
)
}
//打印:1 2 3
- 获取多个元素并依次添加点击事件。
var op = document.querySelectorAll("p");
for (var j = 0; j < op.length; j++) {
op[j].onclick = (function(j) {
return function() {
alert(j);
};
})(j);
}