http://www.planabc.net/2010/04/08/study_sandbox_pattern_in_yui3/
简化了一下 YUI3 中的沙箱实现 方式:
if (typeof Sandbox === 'undefined' || !Sandbox) { Sandbox = function(o) { var self = this; if (!(self instanceof Sandbox)) { // 允许没有 new 操作符的实例化 return new Sandbox(o); } else { self._init(); self._config(o); // 预加载某些指定模块 /* self._setup(); */ // 返回实例本身,支持链式模式 return self; } }; } // Sandbox的(类)静态属性 Sandbox.Env = { /* sidx: 0 , */ mods: {} }; (function() { var p, i, SLICE = Array.prototype.slice, /* instances = {}, */ time = new Date().getTime(), win = window, doc = document; Sandbox.prototype = { // 格式化配置参数 // NOTE:本着简单适用的原则,取消了原先 YUI 中对 loader 的支持 _config: function(o) { var c = this.config, i, j, m, mods; o = o || {}; // mods = c.modules; for (i in o) { if (i == 'win') { c[i] = o[i].contentWindow || o[i]; c.doc = c[i].document; } else { c[i] = o[i]; } } }, /** * 初始化沙箱实例 * @private */ _init: function() { var self = this, G_Env = Sandbox.Env, Env = self.Env; if(!Env) { self.Env = { mods: {}, _used: {}, _attached: {}, _loaded: {} }; Env = self.Env; /* if (G_Env && self !== Sandbox ) { Env._sidx = ++ G_Env.sidx; Env._guid = ('sandbox_' + Env._sidx + '_' + time).replace(/\./g, '_'); } self.id = Env._guid; instances[self.id] = self; */ } self.constructor = Sandbox; self.config = { win: win || {}, doc: doc || {} }; }, // 预留预加载某些指定模块,接口可根据实际需要扩展 /* _setup: function(o) {}, */ /** * 添加模块 * @method add * @param name {string} 模块名 * @param fn {Function} 模块对应的函数 * @param version {string} * @param details 可选配置: * requires - {array} 在本模块执行之前附加的必须的模块数组 * use - {array} 在本模块执行之后附加的模块数组 * */ add: function(name, fn, details) { Sandbox.Env.mods[name] = { name: name, fn: fn, details: details || {} }; return this; // chain support }, /** * 执行与 Sandbox 实例相关联的模块:details.requires--》fn--》details.use * @method _attach * @param r {array} 模块列表数组 * @private */ _attach: function(r) { var mods = Sandbox.Env.mods, self = this, attached = self.Env._attached, i, l = r.length, name, m, fn, d, req, use; for (i = 0; i < l; i = i+1) { name = r[i]; m = mods[name]; if (!attached[name] && m) { attached[name] = true; fn = m.fn; d = m.details; req = d.requires; use = d.use; if (req) { self._attach(req); } if (fn) { fn(self); } if (use) { self._attach(use); } } } }, /** * 绑定模块至 Sandbox 实例 * @param modules* {string} 1-n 个模块 (uses arguments array) * @param *callback {function} callback function 如果包括,必须是最后一个参数。 * * Sandbox().use('planabc.net') * Sandbox().use('planabc.net',function(){}) * Sandbox().use('planabc.net','planabc.com') * Sandbox().use('planabc.net','planabc.com',function(){}) * Sandbox().use('*'); // use all available modules * */ use: function() { var self = this, a = SLICE.call(arguments, 0), mods = Sandbox.Env.mods, used = self.Env._used, loader, firstArg = a[0], callback = a[a.length-1], k, i, l, r = [], process = function(name) { // 添加模块至附加的模块列表 r.push(name); // 一个模块仅附加一次 if (used[name]) { return; } var m = mods[name], req, use, j, jl, t, tl, d = m.details; if (m) { used[name] = true; req = d.requires; use = d.use; } // 附加上 requires 模块 if (req) { for (j = 0,jl = req.length ; j < jl; j = j + 1) { process(req[j]); } } // 附加上 use 模块 if (use) { for (t = 0, tl = use.length; t < tl; t = t + 1) { process(use[t]); } } }, onComplete; if (typeof callback === 'function') { a.pop(); } else { callback = null; } onComplete = function() { if (callback) { callback(self); } }; // Sandbox().use('*'); if (firstArg === "*") { a = []; for (k in mods) { if (mods.hasOwnProperty(k)) { a.push(k); } } if (callback) { a.push(callback); } return self.use.apply(self, a); } l = a.length; // 处理所有必须和附加的模块 for (i = 0; i < l; i = i + 1) { process(a[i]); } self._attach(r); onComplete(); return self; // chain support } }; })();