沙箱模式理解和运用

沙箱模式又称为沙盒模式或者隔离模式

那么什么是沙箱模式呢?

将代码与外界隔离,不管你在里面做什么,都不会污染到全局变量.

沙箱模式的语法结构:

(function () {

})();

沙箱的应用:

1.模拟块级作用域
2.所有的封装的框架都是在沙箱模式中完成

思考?

1.沙箱模式是一种自调用函数那么为什么一定要是自调用函数?

如果需要让代码既能调用又要隔离,就需要一个函数的调用结构
如果不用自调用函数,会造成全局变量污染
能执行,不污染,隔离
基于这个特点有一个非常重要的应用,模拟块级作用域

2.隔离的效果是什么?

使用沙箱后,在内部定义的代码,访问数据,在沙箱内部是一个完整的生态链,
如果要声明多个数据在沙箱中也不会出现污染全局的问题

案例

定义一个数组,数组里面是对象,然后通过for循环给数组里的每一个对象添加一个sayHello方法,最后打印结果
var arr = [{ name:'jim'},
    { name :'tom'},
    {name:'jack'},
   {name:'clark'}];

    for (var i = 0;i<arr.length;i++){
      arr[i].sayHello = function() {
          console.log(arr[i].name);
      };
    }
    for (var k  in arr){
      arr[k].sayHello();
    }

这里写图片描述

for in循环,k是键存放的是索引, 
如果是对象的话得到的每一个索引的名字 
如果是数组的话得到就是索引 

这里等价于

arr[0].sayHello(); 
arr[1].sayHello(); 
arr[2].sayHello();

这里调用sayHello方法执行的是sayHello = function() //{ console.log(arr[i].name)};根据词法作用域,i上下文中没有定义,去上一层找,只有函数才有作用域,所以它的上一级在全局范围内,i的值经过循环最大值是4,数组长度是4,索引值最大是3,所以得到的结果是一个undefined,就会报一个错,不能找到undefined的name属性

解决办法1:

把k改成i就可以了

for (var i  in arr){
      arr[i].sayHello();
    }

这里写图片描述

因为这样等价于

 i = 0
arr[0].sayHello();
i =1
arr[1].sayHello();
i = 2
arr[2].sayHello();

因为for in需要把数组里这个所以赋值给变量i
所以用k改成i就能成功了,但是在这里面说明一个问题,这个for循环不具备块级作用域

解决办法2:

如果把这个for循环放到一个沙箱当中

(function (){
  for (var i = 0; i< arr.length;i++){

      arr[i].sayHello = function() {
          console.log(this.name)
  }
}
})();
for (var i  in arr){
      arr[i].sayHello();
    }

这里写图片描述
代码从上往下执行,沙箱是自调用的,当代码走完的时候其实函数的for循环也执行完了,所以对程序的运行程序没有影响
这时候执行问题就解决了,
好处是函数才能访问作用域,外面访问不到i,有了沙箱模式后就可以模拟块级作用域了

利用沙箱隔离,再举一个例子

用面向对象获取标签

var id= function ( idName){
  retrun document.getElementById( idName );
};
var cName = function (cName){
  retrun document.getElemntsByclassName( cName );
}

这样写会造成全局变量污染
为了解决这个问题可以封装成对象里面
把这个方法变成键值对

var obj = {
   id:function ( idName){
      retrun document.getElementById( idNa
        me );
  },
  cName:function (cName){
      retrun document.getElemntsByclassName( cName );
  }
 };

但这样只是减少了污染,只污染了一个对象,
还有就是无法复用
如果封装构造函数,又会引起多个污染

(function (){
    function test() {};
    test.prototype.extend = function () {};
    //...
    //完成以后
    window.$ = window.jQuery = test;
    //window是全局变量,给全局变量价格$,加个jQuery
    //同时等于test

})();

离开沙箱之后可以直接用$或者jQuery来调用

关于沙箱的复用

复用 体现在两个方面

1.对象->得到一个新对象

2.函数-> 创建新对象,反复调用

var o = {name:'jim',age:19};
(function (window) {
  var f = function(name,age){
    this._name = name;
    this._age = age;
  };
  f.prototype = new Foo();
  function Foo() {}
  window.f = f;
})(window);
var o1 = new f('jim',19);
var o2 = new f('tom',119);

1.提高性能

如果不把window作为参数传进来的话,那么它就会在当前作用域找,看有没有,没有就到上面去找,如果框架里需要频繁用到window的话,那么就要用一次找一次,非常影响性能,所以把window传进去就不用到外面找了,到当前作用域里面找,提高性能 

2.代码压缩

如果不传参数window,不能进行压缩,穿参之后,就能进行压缩,节省很多字节 

(ps:这里的window不是固定的)

沙箱模式的优势:

完全将代码隔离开,在沙箱内部是一个独立的结构,允许根据需要使用各种各样的代码,然后将需要对外公开的代码返回来
不会污染到全局变量,构造函数的复用,添加原型等等都可以在
沙箱内实现
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值