//沙箱//与外界隔绝的一个环境,外界无法修改该环境内任何信息,沙箱内的东西单独属于一个世界//360沙箱模式//将软件和操作系统进行隔离,以达到安全的目的//苹果手的app使用的就是沙箱模式去运行//隔离app的空间,每个app独立运行//JS中的沙箱模式//沙箱模式的基本模型// (function(){
// var a = 123;
// })();var sum = 0;for(var i = 1; i<=100;i++){sum+=i;}console.log(sum);var a =123;(function(){//在沙箱中将所有变量的定义放在最上方//中间就放一些逻辑代码//最后,如果需要,就给外界暴露一些成员(通过window)var sum = 0;for(var i = 1; i<=100;i++){sum+=i;}console.log(sum);})();//为什么要使用立即执行函数表达式(IIFE)//因为IIFE不会再外界暴露任何的全局变量,但是又可以形成一个封闭的空间//刚好可以实现沙箱模式//jQuery当中的沙箱模式(function(win){var itcast = {getEle:function () {}}//如果需要在外界暴露一些属性或者方法,就可以将这些属性和方法//加到window全局对象上去//但是这window全局对象不可以直接引用,因为直接引用会破坏沙箱原则//所以我们选择使用传参的形式将 window对象 传入沙箱内//此时沙箱内使用window对象的时候,不会再去全局搜索window对象//而使用的就是沙箱内部定义的形参win.itCast = win.$ = itcast;})(window)//沙箱模式一般应用在书写第三方框架//或者为第三方框架书写插件//或者书写功能独立的一些组件//沙箱模式的优势//1.沙箱模式使用的是IIFE,不会再外界暴露任何的全局变量,也就不会造成全局变量污染//2.沙箱中的所有数据,都是和外界完全隔离的,外界无法对其进行修改,也就保证了代码的安全性//js中沙箱模式的实现原理就是//函数可以构建作用域!上级作用域不能直接访问下级作用域中的数据
IIFE的用途
严格来讲,IIFE并不是闭包,因为它并不满足函数成为闭包的三个条件。但一般地,人们认为IIFE就是闭包,毕竟闭包有多个定义。
IIFE一般用于构造私有变量,避免全局空间污染
接下来用一个需求实现来更直观地说明IIFE的用途。假设有一个需求,每次调用函数,都返回加1的一个数字(数字初始值为0)
【1】全局变量
一般情况下,我们会使用全局变量来保存该数字状态
var a = 0; function add(){return ++a; } console.log(add());//1 console.log(add());//2
【2】自定义属性
但上面的方法中,变量a实际上只和add函数相关,却声明为全局变量,不太合适。
将变量a更改为函数的自定义属性更为恰当
function add(){return ++add.count; } add.count = 0; console.log(add());//1 console.log(add());//2
【3】IIFE
其实这样做,还是有问题。有些代码可能会无意中将add.count重置
使用IIFE把计数器变量保存为私有变量更安全,同时也可以减少对全局空间的污染
var add = (function(){var counter = 0;return function(){return ++counter; } })(); console.log(add())//1 console.log(add())//2
注意事项
执行如下代码会报错,提示此时的a是undefined
var a = function(){return 1; } (function(){console.log(a());//报错 })();
这是因为没有加分号,浏览器将上面代码解释成如下所示
var a = function(){return 1; }(function(){console.log(a());//报错 })();
如果加上分号,就不会出错了
var a = function(){return 1; }; (function(){console.log(a());//1 })();