YUI3的沙箱机制
YUI2
在YUI2.x里,每一个模块功能的引入都会直接添加在全局的YAHOO里,例如dom.js里:
- var Y = YAHOO.util;
- Y.Dom = {...}
复制代码这样在整个页面范围内,YAHOO.util里就多了一个功能Dom。
YUI3-add()
在YUI3里,每一个模块引入时并没有把功能直接添加到全局的YUI里,看看YUI3里的dom.js:
- YUI.add('dom-base', function(Y) {
- //在这里添加dom方法
- Y.DOM = {
- ...
- }
- ...
- }, '3.0.0' );
复制代码再看看yui.js里add的源码:
- add: function(name, fn, version, details) {
- YUI.Env.mods[name] = {
- name: name,
- fn: fn,
- version: version,
- details: details || {}
- };
- return this; // chain support
- }
复制代码所以YUI3里引入每个模块时只是把这个模块的内容储存在YUI.Evn.mods里。
YUI3-use()
需要使用某个模块时,在创建YUI实例以后,用use取出来执行模块里的程序,为这个YUI实例添加相应的方法:
- YUI().use('dom-base', function(Y) {
- //这里可以用到模块dom-base里对YUI添加的方法Y.DOM
- alert(Y.DOM) //[object object]
- })
复制代码而在同一个页面里,YUI实例里如果没有指明use(’dom-base’),就没有Y.DOM这个方法
- YUI().use('', function(Y) {
- alert(Y.DOM) //undefined
- })
复制代码沙箱
这里YUI().use(”,function(Y){…})就是一个安全沙箱,可以确保这里面的Y是纯天然无污染的,Y实例里有什么功能完全取决于use里传进的模块名称,function(Y){}里面的程序跟外界是隔离的,在里面创建的变量(除了全局变量)以及对YUI的添加修改都不会影响到同个页面上其他人写的程序。
但是这个纯天然无污染是有点代价的,就是每次都要新建一个YUI实例,消耗内存,但如果不怕Y被污染,可以不每次都创建实例:
- var Y = YUI();
- Y.use('dom-base', function(Y) {
- //可以同时使用dom-base和oop模块里添加的方法
- });
- Y.use('oop', function(Y) {
- //可以同时使用dom-base和oop模块里添加的方法
- });
复制代码add()和use()配合一些参数(例如require)和YUI Loader就成了YUI3模块化编程的基础。
最简化的YUI沙箱
去除了YUI Loader以及require等参数
- if (typeof YUI === 'undefined' || !YUI) {
- YUI = function() {
- var Y = this;
- if (!(Y instanceof YUI)) {
- return new YUI();
- } else {
- Y._init();
- return Y;
- }
- };
- }
- //保存mod列表的静态属性
- YUI.Env = {
- mods: {}
- };
- (function() {
- var SLICE = Array.prototype.slice;
- YUI.prototype = {
- _init: function() {
- var Y = this,
- G_Env = YUI.Env,
- Env = Y.Env;
- if(!Env) {
- Y.Env = {
- mods: {},
- _used: {},
- _attached: {}
- };
- Env = Y.Env;
- }
- Y.constructor = YUI;
- },
- add: function(name, fn, details) {
- YUI.Env.mods[name] = {
- name: name,
- fn: fn,
- details: details || {}
- };
- return this; // chain support
- },
- _attach: function(r) {
- var mods = YUI.Env.mods,
- Y = this,
- attached = Y.Env._attached,
- i, l = r.length, name, m, fn, d;
- 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;
- if (fn) {
- fn(Y);
- }
- }
- }
- },
- use: function() {
- var Y = this,
- a = SLICE.call(arguments, 0),
- mods = YUI.Env.mods,
- used = Y.Env._used,
- callback = a[a.length-1],
- i, l,
- r = [],
- process = function(name) {
- // 添加模块至附加的模块列表
- r.push(name);
- // 一个模块仅附加一次
- if (used[name]) {
- return;
- }
- var m = mods[name];
- if (m) {
- used[name] = true;
- }
- },
- onComplete;
- if (typeof callback === 'function') {
- a.pop();
- } else {
- callback = null;
- }
- l = a.length;
- for (i = 0; i < l; i = i + 1) {
- process(a[i]);
- }
- Y._attach(r);
- if (callback) {
- callback(Y);
- }
- return Y; // chain support
- }
- };
- })();
- YUI().add('test',function(){document.write("<p>test module add() excute</p>")});
- YUI().use('test',function(){document.write("<p>test module has executed completely.</p>")});
复制代码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论