沙盘模式可以弥补命名空间模式中的两项不足之处:

  • 使用唯一全局对象作为程序的全局变量入口,使得无法在同一程序中使用两个不同版本的API,因此它们使用的是同一个唯一的全局对象名,如MYAPP;
  • 较长的嵌套对象使得代码编写和解析都比较慢;
沙盘模式,正如其名字所说,提供了一个各类模块可以共同“游戏”的环境,模块之间和沙盘之间不会相互影响。
这种模式在YUI3中大量被使用。下面介绍一种沙盘模式的实现方式:
1. 全局的构造函数
在命名空间模式中只有一个全局对象;在沙盘模式中,唯一的是一个全局的构造函数:比如说,Sandbox()。Sandbox只是本例使用的名字,程序里应该使用一个有具体含义的名字。这个全局的构造函数接受一个回调函数,并为这个回调函数提供沙盘环境。
沙盘构造函数的调用大概是这样的:
new Sandbox(function (box) {
// your code here...
});
对象box就好像命名空间模式中的MYAPP,提供了程序库当中需要的功能。
然后再向沙盘模式加入两样技术:
使用之前提到的检查方法,保证总是用new来调用沙盘构造函数;
沙盘构造函数接受参数,来告知沙盘内应提供哪些模块的功能;
有了这两个技术,我们会检查出Sandbox()不用new来调用,并在Sandbox()内部再用new来调用它自己:保证它总是用new来调用的;并传入适当的参数来通知沙盘提供相应的功能。这样,Sanbox()的调用过程就变成了这样:
Sandbox(['ajax', 'event'], function (box) {
// console.log(box);
});
也可以把要在沙盘中提供的功能模块的名字分别用两个(或多个)参数传入沙盘函数:
Sandbox('ajax', 'dom', function (box) {
// console.log(box);
});
如果程序中有许多模块,并希望一次全部支持所有模块的功能,可以用“*”来代替所有的模块名字,或者更简单地,省略模块名的参数来表示需要所有模块:
Sandbox('*', function (box) {
// console.log(box);
});
Sandbox(function (box) {
// console.log(box);
});
沙盘模式应该足够灵活,并支持在沙盘的回调函数中再次使用沙盘函数:
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
});
以上的例子做法其实就是把需要的功能模块的名字告诉沙盘函数,并把代码段写在回调函数里。这就可以在不形成全局变量污染的情况下,向不同的代码段提供其所需的模块功能支持。被Sandbox()创建的对象相互独立并依赖于不同的功能模块。另外,由于Sandbox是函数,因此它也是对象,所以还可以向Sandbox()加入静态属性来存放一些数据。
2. 定义模块
在 介绍Sandbox的实现之前,先看看如何定义模块。在沙盘模式中,全局的构造函数Sandbox是个函数对象,因此可以为它加入一个静态的属性来保存各 个模块,比如modules。modules是Sandbox的成员属性,也是一个对象,它通过内部的键值对来保存模块,键作为模块名,而值是模块的实 现。定义模块的做法是这样的:
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 () {};
};
上面的例子里,我们给modules对象加入了三个模块,分别是dom,event,以及ajax。
3. 实现Sandbox的沙盘构造函数
一个可行的Sandbox构造函数是这样的(实际上,在你的程序里可能需要把Sandbox改成有意义的名字):
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);
}
}
}
// initialize the required modules
for (i = 0; i < modules.length; i += 1) {
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;
}
};
上面实现里的关键内容包括:
  • 检查this是不是Sandbox的实例,如果不是(说明不是用new调用的Sandbox())就再次用new调用Sandbox;
  • 可以用this为构造函数添加属性,也可以通过prototype来添加属性;
  • 需要使用的模块可以通过模块名的数组传入,也可以使用每个参数一个模块名的方式传入,“*”匹配所有支持的模块(实际的使用中可以还需要引入定义所需模块的js文件);
  • 如果所需的模块已经定义了,就初始化它,也就是执行定义模块的函数;
  • Sandbox函数的最后一个参数是个回调函数,它在Sandbox函数的最后被调用,并使用Sandbox创建的对象来执行相应的代码,这些代码就像在一个沙盘中运行一样:它们得到了需要支持的模块,而且与外部代码相隔离。

JavaScript基础对象创建模式之沙盘模式(026)的更多相关文章

  1. JavaScript基础对象创建模式之单体/单例模式(Singleton)

    首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向整个系统公开这个实例接口 Java中大 ...

  2. JavaScript基础对象创建模式之模块模式(Module Pattern)(025)

    模块模式可以提供软件架构,为不断增长的代码提供组织形式.JavaScript没有提供package的语言表示,但我们可以通过模块模式来分解并组织 代码块,这些黑盒的代码块内的功能可以根据不断变化的软件 ...

  3. JavaScript基础对象创建模式之命名空间(Namespace)模式(022)

    JavaScript中的创建对象的基本方法有字面声明(Object Literal)和构造函数两种,但JavaScript并没有特别的语法来表示如命名空间.模块.包.私有属性.静态属性等等面向对象程序 ...

  4. JavaScript基础对象创建模式之链式调用模式(Chaining Pattern)(029)

    链式调用模式允许一个接一个地调用对象的方法.这种模式不考虑保存函数的返回值,所以整个调用可以在同一行内完成: myobj.method1("hello").method2().me ...

  5. JavaScript基础对象创建模式之静态成员(027)

    在支持“类”的面向对象语言中,静态成员指的是那些所有实例对象共有的类成员.静态成员实际是是“类”的成员,而非“对象”的成员.所以如果 MathUtils类中有个叫 max()的静态成员方法,那么调用这 ...

  6. JavaScript基础对象创建模式之私有属性和方法(024)

    JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: f ...

  7. JavaScript基础对象创建模式之声明依赖模式(023)

    运用了命名空间(Namespace)模式后, 就可以使用一些JavaScript库了,比如YAHOO作用YUI2库的全局对象,可以通过 YAHOO.util.Dom 和 YAHOO.util.Even ...

  8. JavaScript基础对象创建模式之对象的常量(028)

    虽然许多编程语言提供了const关键字来支持常量的声明,但JavaScript里没有表示常量的语义.我们可以用全大写的方式来声明变量,表明它实际上是个常量: Math.PI; // 3.1415926 ...

  9. javascript的对象创建模式---命名空间模式

    javascript中对象的概念是很普遍的,对象是是对象,数组是对象,函数也是对象,字符串其实也是对象.常见的对象创建方法有对象字面量.构造函数创建.我们先来看看对象的创建还有哪些更高级的模式. 一. ...

随机推荐

  1. Spring (一 ) 概述与介绍

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录 1.Spring概述 2.Spring的模块介绍 Spring框架分为四大模块: 3.Eclips ...

  2. WEB前端程序员需要的网站整理

    前端学习资源实在是又多又广,在这样的一个知识的海洋里,我们像一块海绵一样吸收,想要快速提高效率,平时的总结不可缺少,以下总结了一些,排版自我感觉良好,推送出来. 一.插件类网站 jQuery插件库:h ...

  3. java实现风险度量

    X星系的的防卫体系包含 n 个空间站.这 n 个空间站间有 m 条通信链路,构成通信网. 两个空间站间可能直接通信,也可能通过其它空间站中转. 对于两个站点x和y (x != y), 如果能找到一个站 ...

  4. Java实现第九届蓝桥杯哪天返回

    哪天返回 题目描述 小明被不明势力劫持.后被扔到x星站再无问津.小明得知每天都有飞船飞往地球,但需要108元的船票,而他却身无分文. 他决定在x星战打工.好心的老板答应包食宿,第1天给他1元钱. 并且 ...

  5. Java实现第九届蓝桥杯字母阵列

    字母阵列 题目描述 仔细寻找,会发现:在下面的8x8的方阵中,隐藏着字母序列:"LANQIAO". SLANQIAO ZOEXCCGB MOAYWKHI BCCIPLJQ SLAN ...

  6. Hadoop之hadoop fs和hdfs dfs、hdfs fs三者区别

      适用范围 案例 备注 小记 hadoop fs 使用范围最广,对象:可任何对象       hadoop dfs 只HDFS文件系统相关       hdfs fs 只HDFS文件系统相关(包括与 ...

  7. keras搭建神经网络快速入门笔记

    之前学习了tensorflow2.0的小伙伴可能会遇到一些问题,就是在读论文中的代码和一些实战项目往往使用keras+tensorflow1.0搭建, 所以本次和大家一起分享keras如何搭建神经网络 ...

  8. profile(/etc/profile)和bash_profile的区别

    profile(/etc/profile)和bash_profile的区别 profile(/etc/profile),用于设置系统级的环境变量和启动程序,在这个文件下配置会对所有用户生效.当用户登录 ...

  9. C#通过模板导出Word的两种方法(超简单)

    方法一:使用Office的组件 使用该方法必须要安装Office 1.制作Word模板 在需要填充内容的地方增加标识符号,方便之后替换使用,例如 [项目名称],其中[]符号和中间的文字可根据个人情况进 ...

  10. 有趣的 Canvas

    canvas动画狗:https://www.jianshu.com/p/7873307147d5