在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

关于javascript的沙箱模式以及缓存方法的更多相关文章

  1. 关于JavaScript的沙箱模式

    从语言学的角度上来说,允许代码无节制地使用全局变量,是最错误的选择之一.而更可怕的,就是一个变量"可能"成为全局的(在未知的时间与地点).但是这两项,却伴随JavaScript这门 ...

  2. 初涉JavaScript模式 (12) : 沙箱模式

    引子 上一篇说了模块模式,而对于其中的命名空间模式其实也是有着一些问题,比如每添加一个模块或则深入叠加都会导致长命名,并且对于多个库的不同版本同时运行,一不小心就会污染全局标识,而这两天也发现了JSe ...

  3. javascript沙箱模式

    沙箱模式解决了命名空间模式的如下几个缺点: 1.对单个全局变量的依赖变成了应用程序的全局变量依赖.在命名空间模式中,是没有办法使同一个应用程序或库的2个版本运行在同一个页面中.2.对这种以点分割的名字 ...

  4. javascript闭包(Module模式)的用途和高级使用方式

    javascript闭包(Module模式)的用途和高级使用方式 javascript闭包的用途:1. 匿名自执行函数:或者可以理解为,避免污染全局变量2. 缓存:源于闭包的核心特性便是保存状态,应用 ...

  5. JavaScript SandBox沙箱设计模式

    沙箱模式常见于YUI3 core,它是一种采用同一构造器(Constructor)生成彼此独立且互不干扰(self-contained)的实例对象,而从避免污染全局对象的方法. 命名空间 JavaSc ...

  6. JavaScript 沙盒模式

    微前端已经成为前端领域比较火爆的话题,在技术方面,微前端有一个始终绕不过去的话题就是前端沙箱 什么是沙箱 Sandboxie(又叫沙箱.沙盘)即是一个虚拟系统程序,允许你在沙盘环境中运行浏览器或其他程 ...

  7. 深入理解JavaScript中创建对象模式的演变(原型)

    深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...

  8. javascript优化--07模式(对象)02

    沙箱模式: 解决空间命名模式的几个缺点: 命名空间模式中无法同时使用一个应用程序或库的两个版本运行在同一个页面中,因为两者需要相同的全局符号: 以点分割,需要输入更长的字符,解析时间也更长: 全局构造 ...

  9. javascript代码复用模式

    代码复用有一个著名的原则,是GoF提出的:优先使用对象组合,而不是类继承.在javascript中,并没有类的概念,所以代码的复用,也并不局限于类式继承.javascript中创建对象的方法很多,有构 ...

随机推荐

  1. J2SE知识点摘记(二十一)

    实现原理 前面已经提了一下Collection的实现基础都是基于数组的.下面我们就已ArrayList 为例,简单分析一下ArrayList 列表的实现方式.首先,先看下它的构造函数. 下列表格是在S ...

  2. 关于Apple Pay,一篇让你不看就会后悔的文章

    编者按:本文作者康上明学为“小米生活”产品经理,在苹果Apple Pay发布后,他对该产品做了深入研究,带来这篇文章. 对于 Apple Pay ,我有几个疑问: 线下支付是一个庞大复杂的流程,当中涉 ...

  3. 玉兔IM(康林的博客)

    玉兔即时通信 作者:康林(msn.email:kl222@126.com:QQ:16614119) 博客:http://blog.csdn.net/kl222http://blog.csdn.net/ ...

  4. JAVA中的break[标签]continue[标签]用法

    原文:JAVA中的break[标签]continue[标签]用法 注意:JAVA中的标签必须放在循环之前,且中间不能有其他语句.例如:tag:for或while或do--while; 1.使用brea ...

  5. Boost::Thread使用示例 - CG-Animation - 博客频道 - CSDN.NET

    Boost::Thread使用示例 - CG-Animation - 博客频道 - CSDN.NET Boost::Thread使用示例 分类: C/C++ 2011-07-06 14:48 5926 ...

  6. Solrj日期范围查询

    在做依据日期来检索的时候普通的格式化会出错,试了好多种仅仅有一种可行 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH ...

  7. Objective-C中的@dynamic

    一.@dynamic与@synthesize的区别 @property有两个对应的词,一个是@synthesize,一个是@dynamic.如果@synthesize和@dynamic都没写,那么默认 ...

  8. Process Node.js 进程

    Process 进程 process.argv 是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数. process.stdout 标准输出流 co ...

  9. JavaScript之面向对象学九(原型式继承和寄生式继承)

    一.原型式继承 该继承模式是由道格拉斯*克罗克福德在2006年提出的实现继承的方法. 模式的基本思路:借助原型可以基于已有的对象创建新的对象,同时还不必因此创建自定义类型. 代码如下: functio ...

  10. javascript 的加载方式

    本文总结一下浏览器在 javascript 的加载方式. 关键词:异步加载(async loading),延迟加载(lazy loading),延迟执行(lazy execution),async 属 ...