Sandbox.modules = {};
Sandbox.modules.dom = function (box) {
box.getId = function(ele){
return document.getElementById(ele);
};
box.foo = "bar";
};
Sandbox.modules.event = function(box) {
box.click = function (element, callback) {
element.addEventListener('click', callback);
};
};
Sandbox.modules.consoles = function(box) {
box.print = function (msg) {
console.log(msg);
};
};
function Sandbox() {
//将参数转换成一个数组
var args = Array.prototype.slice.call(arguments),
//最后一个参数是回调函数
callback = args.pop(),
//模块可以作为一个数组传递,或作为单独的参数传递
modules = (args[0] && typeof args[0] === 'string') ? args : args[0],i;
//确保该函数
//作为构造函数被调用
if (!(this instanceof Sandbox)) {
return new Sandbox(modules, callback);
}
//需要向'this'添加的属性
this.a = 1;
this.b = 2;
//现在向该核心'this'对象添加模块
//不指定模块名称或'*'都表示使用所有模块
if (!modules || modules === '*') {
modules = [];
for (i in Sandbox.modules) {
if (Sandbox.modules.hasOwnProperty(i)) {
modules.push(i);
}
}
}
//初始化所需的模块
for (i = 0; i<modules.length; i+=1) {
Sandbox.modules[modules[i]](this);
}
callback(this);
//需要的任何原型属性
Sandbox.prototype = {
name: "My Applocation",
version: "10.0",
getName: function() {
return this.name;
}
};
}
//test 1
Sandbox( 'consoles', function(sbox){
sbox.print('this is a test 1');
// console.log(sbox.getId('a').innerHTML);
});
//test 2
Sandbox( 'consoles','dom','event', function(sbox){
sbox.print('this is a test 2');
<span style="white-space:pre"> </span>sbox.print('the property a='+sbox.a);
console.log(sbox.foo);
sbox.click(sbox.getId('inputId'), function () {
alert("callback test!!!~");
});
console.log(sbox.foo);
});
//test 3
new Sandbox(function(box){
box.print('this is a test 3');
});
使用场景:
//使用new操作符
new Sandbox(function(box) {
console.log(box);
})
//忽略new操作符的方法
Sandbox(['ajax', 'event'], function(box) {
console.log(box);
})
//直接传单个参数
Sandbox('ajax', 'dom', function(box) {
console.log(box);
})
//Sandbox的嵌套
Sandbox('dom', 'event', function(box) {
//一些代码
Sandbox('ajax', function(box) {
//这里的box和外部对象的box并不相同
})
})
从上面的代码可以发现沙箱模式可以通过将代码包装到回调函数中从而保护全局命名空间,而且他依赖注入的方式也很好的说明了他需要哪些模块,清晰了整个代码的结构。