在使用其他库中含有与程序中定义的全局实体同名的变量,或者不同的库之间有同名的变量,则在编译时都会出现名字冲突,这就称为全局命名空间污染。
为了避免全局污染,常用闭包实现对某个函数的局部变量的访问,而闭包常用于初始化系统、数据缓存和封装。今天主要讨论一下使用闭包实现数据缓存的实例。
场景1:缓存通过ajax请求的得到的数据
如果第一次访问服务端,则使用ajax访问服务端,并使用闭包缓存数据,下一次再访问,则从闭包中获取数据,直到该页面关闭。
服务端地址:http://localhost:3000/api/2,从服务端获取的数据是json数据,内容和格式如下:
具体实现:
<!DOCTYPEhtml>
<html>
<head>
<metacharset="UTF-8">
<title>使用闭包缓存从服务端的数据</title>
</head>
<body>
<tableborder="1"id="table">
<tr>
<td>FristName</td>
<td>LastName</td>
</tr>
</tbody>
</table>
<buttonid="btn">获取数据</button>
<script>
var count= 0;//计算访问服务端的次数
//点击按钮,加载数据到页面
document.getElementById("btn").onclick= function() {
ajax();
alert(count);
}
//定义闭包
function closureCache() {
//用于缓存数据的局部变量cacheJSON
var cacheJSON= null;
//分别定义getter和setter方法
return {
//getter方法获取cacheJSON
getJSON:function() {
returncacheJSON;
},
//setter方法给cacheJSON赋值
setJSON:function(a) {
cacheJSON =a;
}
}
}
//得到闭包函数
var c= closureCache();
//ajax函数
function ajax() {
//定义通过ajax请求从服务端获取的数据
var ajaxjson= null;
//如果闭包中没有缓存,发起ajax请求
if(c.getJSON()== null) {
varxhr = new XMLHttpRequest();
xhr.open("get","http://localhost:3000/api/2");
xhr.send();
count++;
xhr.onreadystatechange= function() {
if(xhr.readyState== 4 &&xhr.status== 200) {
ajaxjson =JSON.parse(xhr.responseText);
//保存数据到闭包
c.setJSON(ajaxjson);
//动态加载数据到页面
addContentToPage(ajaxjson)
}
}
}
//如果闭包中有缓存,从缓存里拿
else {
ajaxjson=c.getJSON();
}
}
//把从服务端获取的数据渲染到页面上
function addContentToPage(json){
for(vart = 0; t< json['employees'].length; t++) {
vartr = document.createElement("tr");
vartd1 = document.createElement("td");
vartd2 = document.createElement("td");
td1.innerHTML =json['employees'][t]['firstName'];
td2.innerHTML =json['employees'][t]['lastName'];
tr.appendChild(td1);
tr.appendChild(td2);
document.getElementById("table").appendChild(tr);
}
}
</script>
</body>
</html>
场景2:使用闭包缓存5个最近使用的数据
<!DOCTYPEhtml>
<html>
<head>
<metacharset="UTF-8">
<title>使用闭包实现缓存</title>
</head>
<body>
<script>
//定义一个闭包
function resultFun() {
//定义一个变量,用于缓存数据,最多缓存5个
var cache= {};
//计数缓存的个数
var count= 0;
return{
getResult:function(key) {
//如果已经缓存
if(keyin cache) {
console.log("cache");
returncache[key];
}
//如果没缓存
else {
vark = Math.random();
//把数据添加到缓存
cache[key]= k;
//缓存的数据个数加1
count++;
//如果缓存的数据大于等于5
if(count>= 5) {
//通过for循环,删除第一个缓存的数据
for(keyin cache) {
deletecache[key];
break;
}
}
console.log("new");
returnk;
}
}
}
}
varresult=resultFun();
document.write(result.getResult("a")+ "<br/>");
document.write(result.getResult("a")+ "<br/>");
document.write(result.getResult("b")+ "<br/>");
document.write(result.getResult("b")+ "<br/>");
document.write(result.getResult("c")+ "<br/>");
document.write(result.getResult("c")+ "<br/>");
document.write(result.getResult("d")+ "<br/>");
document.write(result.getResult("d")+ "<br/>");
document.write(result.getResult("e")+ "<br/>");
document.write(result.getResult("e")+ "<br/>");
document.write(result.getResult("a")+ "<br/>");
document.write(result.getResult("a")+ "<br/>");
</script>
</body>
</html>