`

javascript沙箱模式

 
阅读更多

沙箱模式常见于YUI3 core,它是一种采用同一构造器(Constructor)生成彼此独立且互不干扰(self-contained)的实例对象,而从避免污染全局对象的方法。

命名空间

JavaScript本身中没有提供命名空间机制,所以为了避免不同函数、对象以及变量名对全局空间的污染,通常的做法是为你的应用程序或者库创建一个唯一的全局对象,然后将所有方法与属性添加到这个对象上。

代码清单1 : 传统命名空间模式

01 /* BEFORE: 5 globals */

02 // constructors

03 function Parent() {}

04 function Child() {}

05 // a variable

06 var some_var = 1;

07 // some objects

08 var module1 = {};

09 module1.data = {a: 1, b: 2};

10 var module2 = {};

11 /* AFTER: 1 global */

12 // global object

13 var MYAPP = {};

14 // constructors

15 MYAPP.Parent = function() {};

16 MYAPP.Child = function() {};

17 // a variable

18 MYAPP.some_var = 1;

19 // an object

20 MYAPP.modules = {};

21 // nested objects

22 MYAPP.modules.module1 = {};

23 MYAPP.modules.module1.data = {a: 1, b: 2};

24 MYAPP.modules.module2 = {};

在这段代码中,你创建了一个全局对象MYAPP,并将其他所有对象、函数作为属性附加到MYAPP上。

通常这是一种较好的避免命名冲突的方法,它被应用在很多项目中,但这种方法有一些缺点。

需要给所有需要添加的函数、变量加上前缀。

因为只有一个全局对象,这意味着一部分代码可以肆意地修改全局对象而导致其余代码的被动更新。

全局构造器

你可以用一个全局构造器,而不是一个全局对象,我们给这个构造器起名为Sandbox(),你可以用这个构造器创建对象,你还可以为构造器传递一个回调函数作为参数,这个回调函数就是你存放代码的独立沙箱环境。

代码清单2:沙箱的使用

1 new Sandbox(function(box){

2     // your code here...

3 });

让我们给沙箱添加点别的特性。

1. 创建沙箱时可以不使用'new'操作符。

2. Sandbox()构造器接受一些额外的配置参数,这些参数定义了生成对象所需模块的名称,我们希望代码更加模块化。

拥有了以上特性后,让我们看看怎样初始化一个对象。

代码清单3显示了你可以在不需要‘new’操作符的情况下,创建一个调用了'ajax'和'event'模块的对象。

代码清单3:以数组的形式传递模块名

1 Sandbox(['ajax', 'event'], function(box){

2     // console.log(box);

3 });

代码清单4:以独立的参数形式传递模块名

1 Sandbox('ajax', 'dom', function(box){

2     // console.log(box);

3 });

代码清单5显示了你可以把通配符'*'作为参数传递给构造器,这意味着调用所有可用的模块,为了方便起见,如果没有向构造器传递任何模块名作为参数,构造器会把'*'作为缺省参数传入。

代码清单5:调用所用可用模块

1 Sandbox('*', function(box){

2     // console.log(box);

3 });

4  

5 Sandbox(function(box){

6     // console.log(box);

7 });

代码清单6显示你可以初始化沙箱对象多次,甚至你可以嵌套它们,而不用担心彼此间会产生任何冲突。

代码清单6:嵌套的沙箱实例

01 Sandbox('dom', 'event', function(box){

02     // work with dom and event

03     Sandbox('ajax', function(box) {

04     // another sandboxed "box" object

05     // this "box" is not the same as

06     // the "box" outside this function

07     //...

08     // done with Ajax

09     });

10     // no trace of Ajax module here

11 });

从上面这些示例可以看出,使用沙箱模式,通过把所有代码逻辑包裹在一个回调函数中,你根据所需模块的不同生成不同的实例,而这些实例彼此互不干扰独立的工作着,从而保护了全局命名空间。

现在让我们看看怎样实现这个Sandbox()构造器。

添加模块

在实现主构造器之前,让我们看看如何向Sandbox()构造器中添加模块。

因为Sandbox()构造器函数也是对象,所以你可以给它添加一个名为’modules'的属性,这个属性将是一个包含一组键值对的对象,其中每对键值对中Key是需要注册的模块名,而Value则是该模块的入口函数,当构造器初始化时当前实例会作为第一个参数传递给入口函数,这样入口函数就能为该实例添加额外的属性与方法。

在代码清单7中,我们添加了'dom','event','ajax'模块。

代码清单7:注册模块

01 Sandbox.modules = {};

02  

03 Sandbox.modules.dom = function(box) {

04     box.getElement = function() {};

05     box.getStyle = function() {};

06     box.foo = "bar";

07 };

08  

09 Sandbox.modules.event = function(box) {

10     // access to the Sandbox prototype if needed:

11     // box.constructor.prototype.m = "mmm";

12     box.attachEvent = function(){};

13     box.dettachEvent = function(){};

14 };

15  

16 Sandbox.modules.ajax = function(box) {

17     box.makeRequest = function() {};

18     box.getResponse = function() {};

19 };

实现构造器

代码清单8描述了实现构造器的方法,其中关键的几个要点:

1. 我们检查this是否为Sandbox的实例,若不是,证明Sandbox没有被new操作符调用,我们将以构造器方式重新调用它。

2. 你可以在构造器内部为this添加属性,同样你也可以为构造器的原型添加属性。

3. 模块名称会以数组、独立参数、通配符‘*’等多种形式传递给构造器。

4. 请注意在这个例子中我们不需要从外部文件中加载模块,但在诸如YUI3中,你可以仅仅加载基础模块(通常被称作种子(seed)),而其他的所有模块则会从外部文件中加载。

5. 一旦我们知道了所需的模块,并初始化他们,这意味着调用了每个模块的入口函数。

6. 回调函数作为参数被最后传入构造器,它将使用最新生成的实例并在最后执行。

代码清单8:实现Sandbox构造器

view source

print?

01 <script>

02 function Sandbox() {

03     // turning arguments into an array

04     var args = Array.prototype.slice.call(arguments),

05     // the last argument is the callback

06     callback = args.pop(),

07     // modules can be passed as an array or as individual parameters

08     modules = (args[0] && typeof args[0] === "string") ?

09     args : args[0],

10     i;

11     // make sure the function is called

12     // as a constructor

13     if (!(this instanceof Sandbox)) {

14         return new Sandbox(modules, callback);

15     }

16     // add properties to 'this' as needed:

17     this.a = 1;

18     this.b = 2;

19     // now add modules to the core 'this' object

20     // no modules or "*" both mean "use all modules"

21     if (!modules || modules === '*') {

22         modules = [];

23             for (i in Sandbox.modules) {

24                 if (Sandbox.modules.hasOwnProperty(i)) {

25                     modules.push(i);

26             }

27         }

28     }

29     // init the required modules

30     for (i = 0; i < modules.length; i++) {

31         Sandbox.modules[modules[i]](this);

32     }

33     // call the callback

34     callback(this);

35 }

36 // any prototype properties as needed

37 Sandbox.prototype = {

38     name: "My Application",

39     version: "1.0",

40     getName: function() {

41         return this.name;

42     }

43 };

44 </script>


分享到:
评论

相关推荐

    JavaScript 设计模式 安全沙箱模式

    JavaScript安全沙箱模式是一种设计模式,主要用于避免JavaScript代码在执行时污染全局命名空间,从而保护全局变量不受影响。该模式常见于YUI3库的核心实现中,它通过利用同一个构造器生成独立的实例对象,这些对象...

    JavaScript模式中文[pdf] 百度云

     沙箱模式  静态成员  对象常量  链模式  method()方法  小结  第6章 代码复用模式  传统与现代继承模式的比较  使用类式继承时的预期结果  类式继承模式#1——默认模式  类式继承模式#2——借用构造函数...

    JS实现闭包中的沙箱模式示例

    沙箱模式是利用闭包实现的一种模块化设计模式,它提供了一种隔离机制,使得模块内的代码不会对全局环境造成污染。本示例通过创建一个自执行函数(Immediately Invoked Function Expression, IIFE)来演示如何在JS中...

    JS沙箱模式实例分析

    沙箱模式在浏览器端的JavaScript编程中尤为重要,尤其在实现第三方广告、小程序、插件等领域得到了广泛的应用。 沙箱模式的实现方法通常依赖于闭包、立即执行函数表达式(IIFE)、以及一些特定的API调用。例如,在...

    JavaScript模式 斯托扬·斯特凡洛夫 著

    沙箱模式 静态成员 对象常量 链模式 method()方法 小结 第6章 代码复用模式 传统与现代继承模式的比较 使用类式继承时的预期结果 类式继承模式#1——默认模式 类式继承模式#2——借用构造函数 类式继承模式#3——...

    js_stuffs:Javascript沙箱

    JavaScript沙箱是一个编程概念,主要用于在安全环境中执行JavaScript代码,防止其对主应用程序或宿主环境造成意外修改或潜在危害。在网页开发中,尤其是在处理用户输入或第三方脚本时,沙箱机制能够确保代码执行的...

    构建以密钥沙箱为核心的安全应用环境.pdf

    2. **操作系统**:操作系统的沙箱模式可能限制应用程序访问文件系统、网络和其他资源。 3. **移动设备**:iOS的App Sandbox和Android的Play Protect等机制为应用提供安全沙箱环境。 ### 密钥沙箱的潜在风险和挑战 ...

    类似Chrome/IE9的沙箱实现

    Chrome和IE9浏览器都采用了沙箱技术来增强其安全性,尤其是对于网页浏览时的插件和JavaScript执行。这种技术的核心思想是将敏感操作限制在一个受控的环境中,即使发生恶意行为,也不会影响到操作系统或用户数据的...

    NodeJS+Vue实现支付宝支付(沙箱)完整流程 .zip

    - 配置沙箱环境:在开放平台中启用沙箱模式,获取沙箱AppKey和沙箱密钥,用于签名和验签。 2. **实现支付接口**: - 使用Alipay SDK:安装对应的NodeJS支付宝SDK,如`alipay-sdk`,它封装了支付宝API,简化了调用...

    DesignPatterns[removed]JavaScript设计模式

    JavaScript-Patterns some demos about JavaScript patterns 文件简介 singleton.js 单体模式 runobject.js ...沙箱模式 method.js 在Function对象上扩展method方法,从而更方便地扩展原型方法 instanceof.js

    Javascript运行exe程序.

    在浏览器中,JavaScript运行在沙箱模式下,受到严格的同源策略限制,不允许直接访问本地文件系统或执行本地程序。而在Node.js环境中,JavaScript可以突破这些限制,因为它设计用于服务器端编程,可以访问文件系统、...

    iBen-js-framework

    为了深入了解这个框架,开发者需要查看源代码,理解其结构和工作原理,包括如何加载模块,如何在沙箱模式下运行代码,以及如何与其他JavaScript库或工具集成。 总的来说,"iBen-js-framework"是一个值得关注的...

    动作沙箱

    1. **源代码**:项目的核心代码,可能是用C++, Python, JavaScript或其他编程语言编写,用于实现动作沙箱的功能。 2. **库和框架**:可能包含了依赖的库和框架,用于处理图形渲染、物理模拟、用户输入和其他动作相关...

    Google V8 for delphi javascript 脚本引擎接口(有demo)

    可以设置V8的安全沙箱模式,限制JavaScript对操作系统资源的访问。 总的来说,"Google V8 for Delphi JavaScript 脚本引擎接口"是一个强大的工具,允许Delphi开发者利用JavaScript的灵活性和易读性,同时享受V8引擎...

    imacros-load-library:在iMacros的沙箱环境中加载第三方库

    iMacros的沙箱模式确保了脚本只能在指定的边界内运行,避免对用户的计算机产生不良影响。然而,这也意味着默认情况下,沙箱环境可能不允许直接加载外部库。 加载第三方库通常涉及到JavaScript的`&lt;script&gt;`标签或者...

    exercises-web:沙箱中的一些基本JavaScript编码挑战和面试问题

    "exercises-web:沙箱中的一些基本JavaScript编码挑战和面试问题"这个资源提供了一系列的编码练习,旨在帮助开发者提升JavaScript技能,并为可能遇到的面试问题做好准备。这个沙箱环境允许用户在安全的环境中实践和...

    CSS沙箱

    4. **安全模式**:CSS沙箱还提供了预定义的安全模式,如`strict`和`unsafe`,分别代表最严格的沙箱环境和几乎无限制的环境,开发者可以根据需求选择。 **三、启用CSS沙箱** 要在`&lt;iframe&gt;`中启用CSS沙箱,需要在`...

    ROPP JAVASCRIPT AMD

    AMD是JavaScript模块化的一种设计模式,特别是在大型复杂Web应用中,它强调异步加载模块。RequireJS是AMD模式的一个典型实现,它允许开发者在不阻塞用户界面的情况下加载依赖项。AMD通过`define`和`require`函数来...

Global site tag (gtag.js) - Google Analytics