在javascript函数代码中,经常会不经意出现全局变量,很可能造成对全局对象的污染,由于这种弊端的存在,那么沙箱模式油然而生。沙箱模式又称为沙盒模式、隔离模式。在js中只有函数可以限定变量作用域,那么想要实现隔离就需要函数。
沙盒模型
(function(){ //代码
})();
其实就是自调用函数,隔离的条件下,既要执行函数,又要不能污染其它对象。
利用沙箱模式模拟块级作用域
var s = 0;
(function(){
for(var i = 0;i <=100;i++){
s += i;
}
console.log(i);//
})();
console.log(i);//i is not defined
凡是在函数中定义的变量,应当将变量提到前面
经典案例介绍
function fn(a){
var result = [];
for(var i = 0,n = a.length;i < n;i++){
result[i] = function(){
return a[i];//此时i的值为3
};
}
return result;
}
var o = fn([10,20,30])
var f = o[0];
console.log(f());//undefined //下面函数用到了沙箱模式
function fn(a){
var result = [];
for(var i = 0,n = a.length;i < n;i++){
(function(){
var j = i;
result[i] = function(){
return a[j];
};
})();
}
return result;
}
var o = fn([10,20,30])
var f = o[1];
console.log(f());//
// 也可以这么写
function fn(a){
var result = [];
for(var i = 0,n = a.length;i < n;i++){
(function(j){result[i] = function(){return a[j];};
})(i);
}
return result;
}
var o = fn([10,20,30])
var f = o[2];
console.log(f());//
从上面函数可以看出,沙箱模式的优点
jQuery中缓存方法的分析
先看一个用闭包的缓存
var createCache = function(){
var internalCache = {};//定义一个空对象用于接收数据
var arr = [];//定义一个空数组用于接收数据并排序
return function ( k, v ) {//在这用到闭包模式
if ( v ) {
if ( !internalCache[ k ] ) {//判断缓存中是否有该数据,有则往下进行
if ( arr.length >= 3 ) {//假设缓存极限为3
var deleteKey = arr.shift();//截取数组第一个值返回该值
delete internalCache[ deleteKey ];//删除对象中的该值
}
arr.push( k ); // 缓存中没有数据的时候才会加进去
}
internalCache[ k ] = v;//匹配键值对
} else {
return internalCache[ k ];//
}
return internalCache;//返回该对象
};
}; var o = createCache();
o('oName', 'jim');
o('Name', 'yy');
o('gender','girl')
o('age', 24);
console.log(o('age', 24));//Object {Name: "yy", genser: "girl", age: 24} 在打印最后一个数据时,最后得到3个,可以看出数据已经缓存
console.log( o(['oName']) );//undefined
console.log( o(['Name']) );//yy
console.log( o(['age']) );//24
上面方法的优点:如果传入一个函数则少一变量,这样占用内存少。缺点就是数据暴露在外面,有安全隐患。
对以上函数作出改良
1、将键值对模型从闭包中提取出来, 放到函数名上
2、 既然键值对存储在函数名上, 那么表示直接用 函数名[ key ] 就可以访问数据了
var createCache = function(){
var arr = [];
var cache = function ( k, v ) {
if ( !cache[ k ] ) {
if ( arr.length >= 3 ) {
var deleteKey = arr.shift();
delete cache[ deleteKey ];//递归
}
arr.push( k ); // 缓存中没有数据的时候才会加进去
}
cache[ k ] = v;
};
return cache;
}; var o = createCache();
o('oName', 'jim');
o('Name', 'yy');
o('gender','girl')
o('age', 24);
console.log( o['oName'] );//undefined
console.log( o['Name']);//yy
console.log( o['gender'] );//girl
再进一步改良,在jQuery中目标含明确,调用函数就是在缓存数据,没有修改数据的意图,无须判断该键(k)的存在
var createCache = function(){
var arr = [];
var cache = function ( k, v ) {
if ( arr.length >= 3 ) {//假设缓存数据的数量极限是3
delete cache[ arr.shift() ];//递归调用
}
arr.push( k ); // 缓存中没有数据的时候才会加进去
cache[ k ] = v;
};
return cache;
};
var o = createCache();
o('oName', 'jim');
o('Name', 'yy');
o('gender','girl')
o('age', 24);
console.log( o['oName'] );//undefined
console.log( o['Name']);//yy
console.log( o['gender'] );//girl