欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript 設(shè)計(jì)模式 安全沙箱模式

 更新時(shí)間:2010年09月24日 12:13:20   作者:  
沙箱模式常見(jiàn)于YUI3 core,它是一種采用同一構(gòu)造器(Constructor)生成彼此獨(dú)立且互不干擾(self-contained)的實(shí)例對(duì)象,而從避免污染全局對(duì)象的方法

命名空間

  JavaScript本身中沒(méi)有提供命名空間機(jī)制,所以為了避免不同函數(shù)、對(duì)象以及變量名對(duì)全局空間的污染,通常的做法是為你的應(yīng)用程序或者庫(kù)創(chuàng)建一個(gè)唯一的全局對(duì)象,然后將所有方法與屬性添加到這個(gè)對(duì)象上。

復(fù)制代碼 代碼如下:

/* BEFORE: 5 globals */
// constructors
function Parent() {}
function Child() {}
// a variable
var some_var = 1;
// some objects
var module1 = {};
module1.data = {a: 1, b: 2};
var module2 = {};
/* AFTER: 1 global */
// global object
var MYAPP = {};
// constructors
MYAPP.Parent = function() {};
MYAPP.Child = function() {};
// a variable
MYAPP.some_var = 1;
// an object
MYAPP.modules = {};
// nested objects
MYAPP.modules.module1 = {};
MYAPP.modules.module1.data = {a: 1, b: 2};
MYAPP.modules.module2 = {};

代碼清單1 : 傳統(tǒng)命名空間模式


  在這段代碼中,你創(chuàng)建了一個(gè)全局對(duì)象MYAPP,并將其他所有對(duì)象、函數(shù)作為屬性附加到MYAPP上.

  通常這是一種較好的避免命名沖突的方法,它被應(yīng)用在很多項(xiàng)目中,但這種方法有一些缺點(diǎn)。

  1.需要給所有需要添加的函數(shù)、變量加上前綴。
  2.因?yàn)橹挥幸粋€(gè)全局對(duì)象,這意味著一部分代碼可以肆意地修改全局對(duì)象而導(dǎo)致其余代碼的被動(dòng)更新。

  全局構(gòu)造器

  你可以用一個(gè)全局構(gòu)造器,而不是一個(gè)全局對(duì)象,我們給這個(gè)構(gòu)造器起名為Sandbox(),你可以用這個(gè)構(gòu)造器創(chuàng)建對(duì)象,你還可以為構(gòu)造器傳遞一個(gè)回調(diào)函數(shù)作為參數(shù),這個(gè)回調(diào)函數(shù)就是你存放代碼的獨(dú)立沙箱環(huán)境。
復(fù)制代碼 代碼如下:

new Sandbox(function(box){
   // your code here...
});

代碼清單2:沙箱的使用


  讓我們給沙箱添加點(diǎn)別的特性


  1.創(chuàng)建沙箱時(shí)可以不使用'new'操作符

  2.Sandbox()構(gòu)造器接受一些額外的配置參數(shù),這些參數(shù)定義了生成對(duì)象所需模塊的名稱,我們希望代碼更加模塊化。


  擁有了以上特性后,讓我們看看怎樣初始化一個(gè)對(duì)象。


  代碼清單3顯示了你可以在不需要‘new'操作符的情況下,創(chuàng)建一個(gè)調(diào)用了'ajax'和'event'模塊的對(duì)象.


復(fù)制代碼 代碼如下:

Sandbox(['ajax', 'event'], function(box){
   // console.log(box);
});

代碼清單3:以數(shù)組的形式傳遞模塊名
復(fù)制代碼 代碼如下:

Sandbox('ajax', 'dom', function(box){
   // console.log(box);
});

代碼清單4:以獨(dú)立的參數(shù)形式傳遞模塊名

  代碼清單5顯示了你可以把通配符'*'作為參數(shù)傳遞給構(gòu)造器,這意味著調(diào)用所有可用的模塊,為了方便起見(jiàn),如果沒(méi)有向構(gòu)造器傳遞任何模塊名作為參數(shù),構(gòu)造器會(huì)把'*'作為缺省參數(shù)傳入.

復(fù)制代碼 代碼如下:

Sandbox('*', function(box){
   // console.log(box);
});
Sandbox(function(box){
   // console.log(box);
});

代碼清單5:調(diào)用所用可用模塊


  代碼清單6顯示你可以初始化沙箱對(duì)象多次,甚至你可以嵌套它們,而不用擔(dān)心彼此間會(huì)產(chǎn)生任何沖突.
復(fù)制代碼 代碼如下:

Sandbox('dom', 'event', function(box){
// work with dom and event
   Sandbox('ajax', function(box) {
   // another sandboxed "box" object
  // this "box" is not the same as
  // the "box" outside this function
  //...
  // done with Ajax
   });
// no trace of Ajax module here
});

代碼清單6:嵌套的沙箱實(shí)例

  從上面這些示例可以看出,使用沙箱模式,通過(guò)把所有代碼邏輯包裹在一個(gè)回調(diào)函數(shù)中,你根據(jù)所需模塊的不同生成不同的實(shí)例,而這些實(shí)例彼此互不干擾獨(dú)立的工作著,從而保護(hù)了全局命名空間。

  現(xiàn)在讓我們看看怎樣實(shí)現(xiàn)這個(gè)Sandbox()構(gòu)造器.


  添加模塊

  在實(shí)現(xiàn)主構(gòu)造器之前,讓我們看看如何向Sandbox()構(gòu)造器中添加模塊。

  因?yàn)镾andbox()構(gòu)造器函數(shù)也是對(duì)象,所以你可以給它添加一個(gè)名為'modules'的屬性,這個(gè)屬性將是一個(gè)包含一組鍵值對(duì)的對(duì)象,其中每對(duì)鍵值對(duì)中Key是需要注冊(cè)的模塊名,而Value則是該模塊的入口函數(shù),當(dāng)構(gòu)造器初始化時(shí)當(dāng)前實(shí)例會(huì)作為第一個(gè)參數(shù)傳遞給入口函數(shù),這樣入口函數(shù)就能為該實(shí)例添加額外的屬性與方法。

  在代碼清單7中,我們添加了'dom','event','ajax'模塊。

復(fù)制代碼 代碼如下:

Sandbox.modules = {};
Sandbox.modules.dom = function(box) {
  box.getElement = function() {};
  box.getStyle = function() {};
  box.foo = "bar";
};
Sandbox.modules.event = function(box) {
// access to the Sandbox prototype if needed:
// box.constructor.prototype.m = "mmm";
   box.attachEvent = function(){};
  box.dettachEvent = function(){};
};
Sandbox.modules.ajax = function(box) {
  box.makeRequest = function() {};
  box.getResponse = function() {};
};

代碼清單7:注冊(cè)模塊


  實(shí)現(xiàn)構(gòu)造器

  代碼清單8描述了實(shí)現(xiàn)構(gòu)造器的方法,其中關(guān)鍵的幾個(gè)要點(diǎn):

  1.我們檢查this是否為Sandbox的實(shí)例,若不是,證明Sandbox沒(méi)有被new操作符調(diào)用,我們將以構(gòu)造器方式重新調(diào)用它。
  2.你可以在構(gòu)造器內(nèi)部為this添加屬性,同樣你也可以為構(gòu)造器的原型添加屬性。
  3.模塊名稱會(huì)以數(shù)組、獨(dú)立參數(shù)、通配符‘*'等多種形式傳遞給構(gòu)造器。
  4.請(qǐng)注意在這個(gè)例子中我們不需要從外部文件中加載模塊,但在諸如YUI3中,你可以僅僅加載基礎(chǔ)模塊(通常被稱作種子(seed)),而其他的所有模塊則會(huì)從外部文件中加載。
  5.一旦我們知道了所需的模塊,并初始化他們,這意味著調(diào)用了每個(gè)模塊的入口函數(shù)。
  6.回調(diào)函數(shù)作為參數(shù)被最后傳入構(gòu)造器,它將使用最新生成的實(shí)例并在最后執(zhí)行。
復(fù)制代碼 代碼如下:

function Sandbox() {
   // turning arguments into an array
   var args = Array.prototype.slice.call(arguments),
   // the last argument is the callback
     callback = args.pop(),
   // modules can be passed as an array or as individual parameters
     modules = (args[0] && typeof args[0] === "string") ?
    args : args[0],
    i;
     // make sure the function is called
    // as a constructor
   if (!(this instanceof Sandbox)) {
     return new Sandbox(modules, callback);
  }
  // add properties to 'this' as needed:
  this.a = 1;
  this.b = 2;
  // now add modules to the core 'this' object
  // no modules or "*" both mean "use all modules"
  if (!modules || modules === '*') {
    modules = [];
    for (i in Sandbox.modules) {
      if (Sandbox.modules.hasOwnProperty(i)) {
        modules.push(i);
      }
     }
   }
  // init the required modules
  for (i = 0; i < modules.length; i++) {
    Sandbox.modules[modules[i]](this);
  }
  // call the callback
  callback(this);
}
// any prototype properties as needed
Sandbox.prototype = {
  name: "My Application",
  version: "1.0",
  getName: function() {
    return this.name;
  }
};

代碼清單8:實(shí)現(xiàn)Sandbox構(gòu)造器
原文來(lái)自:Stoyan Stefanov - JavaScript Patterns Part 7:The Sandbox Pattern

相關(guān)文章

最新評(píng)論