YUI3的沙箱机制

发布于 2022-09-06 08:05:11 字数 10224 浏览 11 评论 0

YUI2
在YUI2.x里,每一个模块功能的引入都会直接添加在全局的YAHOO里,例如dom.js里:

  1. var Y = YAHOO.util;
  2. Y.Dom = {...}

复制代码这样在整个页面范围内,YAHOO.util里就多了一个功能Dom。

YUI3-add()
在YUI3里,每一个模块引入时并没有把功能直接添加到全局的YUI里,看看YUI3里的dom.js:

  1. YUI.add('dom-base', function(Y) {
  2.     //在这里添加dom方法
  3.     Y.DOM = {
  4.         ...
  5.     }
  6. ...
  7. }, '3.0.0' );

复制代码再看看yui.js里add的源码:

  1. add: function(name, fn, version, details) {
  2.     YUI.Env.mods[name] = {
  3.         name: name,
  4.         fn: fn,
  5.         version: version,
  6.         details: details || {}
  7.     };
  8.     return this; // chain support
  9. }

复制代码所以YUI3里引入每个模块时只是把这个模块的内容储存在YUI.Evn.mods里。

YUI3-use()
需要使用某个模块时,在创建YUI实例以后,用use取出来执行模块里的程序,为这个YUI实例添加相应的方法:

  1. YUI().use('dom-base', function(Y) {
  2.     //这里可以用到模块dom-base里对YUI添加的方法Y.DOM
  3.     alert(Y.DOM) //[object object]
  4. })

复制代码而在同一个页面里,YUI实例里如果没有指明use(’dom-base’),就没有Y.DOM这个方法

  1. YUI().use('', function(Y) {
  2.     alert(Y.DOM) //undefined
  3. })

复制代码沙箱
这里YUI().use(”,function(Y){…})就是一个安全沙箱,可以确保这里面的Y是纯天然无污染的,Y实例里有什么功能完全取决于use里传进的模块名称,function(Y){}里面的程序跟外界是隔离的,在里面创建的变量(除了全局变量)以及对YUI的添加修改都不会影响到同个页面上其他人写的程序。

但是这个纯天然无污染是有点代价的,就是每次都要新建一个YUI实例,消耗内存,但如果不怕Y被污染,可以不每次都创建实例:

  1. var Y = YUI();
  2. Y.use('dom-base', function(Y) {
  3.     //可以同时使用dom-base和oop模块里添加的方法
  4. });
  5. Y.use('oop', function(Y) {
  6.     //可以同时使用dom-base和oop模块里添加的方法
  7. });

复制代码add()和use()配合一些参数(例如require)和YUI Loader就成了YUI3模块化编程的基础。

最简化的YUI沙箱
去除了YUI Loader以及require等参数

  1. if (typeof YUI === 'undefined' || !YUI) {
  2.     YUI = function() {
  3.         var Y = this;
  4.         if (!(Y instanceof YUI)) {
  5.             return new YUI();
  6.         } else {
  7.             Y._init();
  8.             return Y;
  9.         }
  10.     };
  11. }
  12. //保存mod列表的静态属性
  13. YUI.Env = {
  14.     mods: {}
  15. };
  16. (function() {
  17.     var SLICE = Array.prototype.slice;
  18.     YUI.prototype = {
  19.         _init: function() {
  20.             var Y  = this,
  21.                 G_Env = YUI.Env,
  22.                 Env   = Y.Env;
  23.             if(!Env) {
  24.                 Y.Env = {
  25.                     mods: {},
  26.                     _used: {},
  27.                     _attached: {}
  28.                 };
  29.                 Env = Y.Env;
  30.             }
  31.             Y.constructor = YUI;
  32.         },
  33.         add: function(name, fn, details) {
  34.             YUI.Env.mods[name] = {
  35.                 name: name,
  36.                 fn: fn,
  37.                 details: details || {}
  38.             };
  39.             return this; // chain support
  40.         },
  41.         _attach: function(r) {
  42.             var mods = YUI.Env.mods,
  43.                 Y = this,
  44.                 attached = Y.Env._attached,
  45.                 i, l = r.length, name, m, fn, d;
  46.             for (i = 0; i < l; i = i+1) {
  47.                 name = r[i];
  48.                 m    = mods[name];
  49.                 if (!attached[name] && m) {
  50.                     attached[name] = true;
  51.                     fn  = m.fn;
  52.                     d   = m.details;
  53.                     if (fn) {
  54.                         fn(Y);
  55.                     }
  56.                 }
  57.             }
  58.         },
  59.         use: function() {
  60.             var Y = this,
  61.                 a = SLICE.call(arguments, 0),
  62.                 mods = YUI.Env.mods,
  63.                 used = Y.Env._used,
  64.                 callback = a[a.length-1],
  65.                 i, l,
  66.                 r = [],
  67.                 process = function(name) {
  68.                     // 添加模块至附加的模块列表
  69.                     r.push(name);
  70.                     // 一个模块仅附加一次
  71.                     if (used[name]) {
  72.                         return;
  73.                     }
  74.                     var m = mods[name];
  75.                     if (m) {
  76.                         used[name] = true;
  77.                     }
  78.                 },
  79.                 onComplete;
  80.             if (typeof callback === 'function') {
  81.                 a.pop();
  82.             } else {
  83.                 callback = null;
  84.             }
  85.                         l = a.length;
  86.                         for (i = 0; i < l; i = i + 1) {
  87.                 process(a[i]);
  88.             }
  89.             Y._attach(r);
  90.                         if (callback) {
  91.                                 callback(Y);
  92.                         }
  93.             return Y; // chain support
  94.         }
  95.     };
  96. })();
  97. YUI().add('test',function(){document.write("<p>test module add() excute</p>")});
  98. YUI().use('test',function(){document.write("<p>test module has executed completely.</p>")});

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文