JavaScript中的创建对象的基本方法有字面声明(Object Literal)和构造函数两种,但JavaScript并没有特别的语法来表示如命名空间、模块、包、私有属性、静态属性等等面向对象程序设计中的概 念。为了让JavaScript实现面向对象程序中的高级语义,人们发明了命名空间模式、依赖声明模式,模块模式,以及沙盘模式。

1. 命名空间模式
命 名空间模式解决了JavaScript中的两个问题,一是全局变量污染的问题,二是可能的名字冲突问题。虽然JavaScript没有特别支持命名空间, 但命名空间模式在JavaScript中并不难实现。为了不过多使用全局变量,可以把程序中所有使用到的全局变量组织到一个(最好是一个程序只有一个)全 局的对象中去。接下来,要访问需要的变量,就可以通过这个对象来得到引用:
// BEFORE: 5 globals
// Warning: antipattern
// constructors
function Parent() {}
function Child() {}
// a variable
var some_var = 1;
// some objects
var module1 = {};
module1.data = {a: 1, b: 2};
var module2 = {};
上面的代码里有5个全局变量,有全局的对象,也有全局的简单类型的变量。下面建立一个全局对象,名字比如说叫MYAPP,然后把上面的5个全局变量都组织到MYAPP里:
// AFTER: 1 global
// global object
var MYAPP = {};
// constructors
MYAPP.Parent = function () {};
MYAPP.Child = function () {};
// a variable
MYAPP.some_var = 1;
// an object container
MYAPP.modules = {};
// nested objects
MYAPP.modules.module1 = {};
MYAPP.modules.module1.data = {a: 1, b: 2};
MYAPP.modules.module2 = {};
这个全局对象的名字,可以选择使用程序的名字,也可以用域名,也可以用公司名。通常这个全局对象的名字是全大写的,以便看起来醒目些,但它并不是常量(常量通常也是全大写的)。
这种模式可以很好的解决命名冲突的问题,因为不同程序或公司的代码里使用的变量,都被组织到不同的全局对象中,因此许多JavaScript的库都是用这种方式来组织API的。但这种模式也有些小问题:
  • 变量使用起来需要敲更多的字母,js文件也因此变得更大;
  • 只有一个全局变量使得所有的代码都可以使用它并修改它,这种修改可以即时生效;
  • 长的嵌套的名字使得变量的解析过程需要更长的时间。
后面还将介绍的沙盘模式将应对这些问题。

2. 通用的命名空间函数

当程序变得越来越大之后,使用这个变量之前才在全局对象中声明它变得不再安全:一些属性和对象可能已经在全局对象中存在,重新声明它将把它原有的内容覆盖,因此我们在声明变量时就需要先做个简单的检查:
// unsafe
var MYAPP = {};
// better
if (typeof MYAPP === "undefined") {
var MYAPP = {};
}
// or shorter
var MYAPP = MYAPP || {};
上面的检查是简单有效的,但十分繁琐: 在使用MYAPP.modules.module2这前,需要做3次检查。因此就需要有一个叫namespace()的函数,在每次使用声明一个模块或变量之前,做相应的检查:
// using a namespace function
MYAPP.namespace('MYAPP.modules.module2');
// equivalent to:
// var MYAPP = {
// modules: {
// module2: {}
// }
// };
下面就是一个通用的namespace()函数的实现:
var MYAPP = MYAPP || {};
MYAPP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP,
i;
// strip redundant leading global
if (parts[0] === "MYAPP") {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
// create a property if it doesn't exist
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
有了上面的namespace()函数,我们就可以这样做了:
// assign returned value to a local var
var module2 = MYAPP.namespace('MYAPP.modules.module2');
module2 === MYAPP.modules.module2; // true
// skip initial `MYAPP`
MYAPP.namespace('modules.module51');
// long namespace
MYAPP.namespace('once.upon.a.time.there.was.this.long.nested.property');
这样我们就声明了一个很长的嵌套命名空间:

JavaScript基础对象创建模式之命名空间(Namespace)模式(022)的更多相关文章

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

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

  2. JavaScript基础对象创建模式之沙盘模式(026)

    沙盘模式可以弥补命名空间模式中的两项不足之处: 使用唯一全局对象作为程序的全局变量入口,使得无法在同一程序中使用两个不同版本的API,因此它们使用的是同一个唯一的全局对象名,如MYAPP: 较长的嵌套 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 用js数组实现最原始的图片轮播实现

    上班以来看到了,写了很多的轮播图效果,实现方法大致有 1.将图片局对定位,利用z-index和opacity实现图片渐现 2.用css3 的transtion:Xx xx left/right,实现左 ...

  2. Java实现 LeetCode 8 字符串转换整数(atoi)

    8. 字符串转换整数 (atoi) 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非 ...

  3. Java实现表达式计算求值

    问题描述 输入一个只包含加减乖除和括号的合法表达式,求表达式的值.其中除表示整除. 输入格式 输入一行,包含一个表达式. 输出格式 输出这个表达式的值. 样例输入 1-2+3*(4-5) 样例输出 - ...

  4. java实现 洛谷 P1017 进制转换

    import java.util.Scanner; public class Main { private static Scanner cin; public static void main(St ...

  5. Java实现 蓝桥杯 算法提高 矩阵翻转

    问题描述 Ciel有一个N*N的矩阵,每个格子里都有一个整数. N是一个奇数,设X = (N+1)/2.Ciel每次都可以做这样的一次操作:他从矩阵选出一个X*X的子矩阵,并将这个子矩阵中的所有整数都 ...

  6. java实现自行车行程

    ** 自行车行程** 计算行程 低碳生活,有氧运动.骑自行车出行是个好主意.小明为自己的自行车装了个计数器,可以计算出轮子转动的圈数.在一次骑车旅行中,出发时计算器的示数为begin,到达目的地时的示 ...

  7. Java实现第九届蓝桥杯猴子分香蕉

    猴子分香蕉 题目描述 5只猴子是好朋友,在海边的椰子树上睡着了.这期间,有商船把一大堆香蕉忘记在沙滩上离去. 第1只猴子醒来,把香蕉均分成5堆,还剩下1个,就吃掉并把自己的一份藏起来继续睡觉. 第2只 ...

  8. 优雅的敲JS代码的几个原则

    一.条件语句        1,使用 Array.includes 来处理多重 || 条件          // ----- 一般 ------ if (fruit == 'apple' || fr ...

  9. 【1】svn 指令总结

    [1]svn log 1.svn log 2. [2]svn di [3]

  10. 简单说维特比算法 - python实现

    动态规划求最短路径算法,与穷举法相比优点在于大大降低了时间复杂度; 假如从起点A到终点S的最短路径Road经过点B1,那么从起点A到B1的最短路径的终点就是B1,否则如果存在一个B2使得A到B2的距离 ...