热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JavaScript设计模式安全沙箱模式_js面向对象

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

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

代码如下:


/* 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 : 传统命名空间模式


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

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

  1.需要给所有需要添加的函数、变量加上前缀。
  2.因为只有一个全局对象,这意味着一部分代码可以肆意地修改全局对象而导致其余代码的被动更新。

  全局构造器

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

代码如下:


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


代码清单2:沙箱的使用


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


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

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


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


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


代码如下:


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


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

代码如下:


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


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

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

代码如下:


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


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


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

代码如下:


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:嵌套的沙箱实例

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

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


  添加模块

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

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

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

代码如下:


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:注册模块


  实现构造器

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

  1.我们检查this是否为Sandbox的实例,若不是,证明Sandbox没有被new操作符调用,我们将以构造器方式重新调用它。
  2.你可以在构造器内部为this添加属性,同样你也可以为构造器的原型添加属性。
  3.模块名称会以数组、独立参数、通配符‘*'等多种形式传递给构造器。
  4.请注意在这个例子中我们不需要从外部文件中加载模块,但在诸如YUI3中,你可以仅仅加载基础模块(通常被称作种子(seed)),而其他的所有模块则会从外部文件中加载。
  5.一旦我们知道了所需的模块,并初始化他们,这意味着调用了每个模块的入口函数。
  6.回调函数作为参数被最后传入构造器,它将使用最新生成的实例并在最后执行。

代码如下:


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 inpidual 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     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:实现Sandbox构造器
原文来自:Stoyan Stefanov - Javascript Patterns Part 7:The Sandbox Pattern
推荐阅读
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 本文介绍了使用FormData对象上传文件同时附带其他参数的方法。通过创建一个表单,将文件和参数添加到FormData对象中,然后使用ajax发送POST请求进行文件上传。在发送请求时,需要设置processData为false,告诉jquery不要处理发送的数据;同时设置contentType为false,告诉jquery不要设置content-Type请求头。 ... [详细]
  • 本文介绍了DataTables插件的官方网站以及其基本特点和使用方法,包括分页处理、数据过滤、数据排序、数据类型检测、列宽度自动适应、CSS定制样式、隐藏列等功能。同时还介绍了其易用性、可扩展性和灵活性,以及国际化和动态创建表格的功能。此外,还提供了参数初始化和延迟加载的示例代码。 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • 查询单个functionquery(id){$.ajax({url:smallproductServlet,async:true,type:POST,data:{typ ... [详细]
  • 工作经验谈之-让百度地图API调用数据库内容 及详解
    这段时间,所在项目中要用到的一个模块,就是让数据库中的内容在百度地图上展现出来,如经纬度。主要实现以下几点功能:1.读取数据库中的经纬度值在百度上标注出来。2.点击标注弹出对应信息。3 ... [详细]
  • Allegro总结:1.防焊层(SolderMask):又称绿油层,PCB非布线层,用于制成丝网印板,将不需要焊接的地方涂上防焊剂.在防焊层上预留的焊盘大小要比实际的焊盘大一些,其差值一般 ... [详细]
  • 前言:关于跨域CORS1.没有跨域时,ajax默认是带cookie的2.跨域时,两种解决方案:1)服务器端在filter中配置详情:http:blog.csdn.netwzl002 ... [详细]
  • ASP.NET&Spring.NET&NHibernate最佳实践(五)——第3章人事子系统(2)
    3.4.人事子系统服务层(Service)部门服务接口(IDeptService.cs)usingSystem;usingGuushuuse.SalaryPrj. ... [详细]
  • Python入门后,想要从事自由职业可以做哪方面工作?1.爬虫很多人入门Python的必修课之一就是web开发和爬虫。但是这两项想要赚钱的话 ... [详细]
  • 一、Struts2是一个基于MVC设计模式的Web应用框架在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2优点1、实现 ... [详细]
  • XMLhttpREquest_Ajax技术总结之XmlHttpRequest
    Ajax1、 什么是ajax   ... [详细]
  • 比如,我在数据库的num=1,我在页面上显示了1,但是我现在把数据库的num=2,那么怎么实现到那个网页无刷新的更新2了。求大神,最好有个例子,ajax的方法 ... [详细]
  • 我将SpringMVC升级到Spring3.2.5.我的一些剩余调用即使存在,也会返回无法识别的字段异常.这是错误.Resolvingexceptionfrom ... [详细]
author-avatar
手机用户2502852637_666
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有