这又是一个新的开始,对象的重要性不言而喻。在JavaScript中创建对象是十分容易的,之前聊过的对象字面量和构造函数都可以达到目的。但是本篇中,我们越过那些方法,以寻求一些额外的对象创建模式。

  本篇内容,我们将学到命名空间(namespace),依赖声明(dependency declaration)、模块模式(module pattern)、沙箱模式(sandbox pattern)。它们都可以帮助您组织应用程序代码的结构,并且降低隐含的全局变量带来的后果。其他讨论的主题包括私有和特权成员、对象常量、链和一个启发类的方式以以定义构造函数。

一、命名空间模式

  命名空间(namespace)有助于减少程序中所需要的全局变量的数量,并且同时还有助于避免命名冲突或过长的名字前缀。

  JavaScript语言的语法中并没有内置命名空间,但是这种特征是非常容易实现的。可以为应用程序或库创建一个(理想上最好只有一个)全局对象,然后可以将所有功能添加到该全局对象中,从而在有大量函数、对象和其他变量的情况下并不会污染全局范围。

// 5个全局变量
// 警告:反模式
// 构造函数
function Parent() {}
function Child() {} // 一个变量
var some_var = 1; // 一些对象
var module1 = {};
module1.data = {a:1,b:2};
var module2 = {}; // 可以通过为应用程序创建一个全局对象这种方式来重构上面这种类型的代码:
// 之后:1个全局变量
// 全局变量
var MYAPP = {}; // 构造函数
MYAPP.Parent = function () {};
MYAPP.Child = function () {}; // 一个变量
MYAPP.some_var = 1; // 一个对象容器
MYAPP.modules = {}; // 嵌套对象
MYAPP.modules.module1 = {};
MYAPP.modules.module1.data = {a:1,b:2};
MYAPP.modules.module2 = {};

  对于全局命名空间对象的名称,可以任意选择,比如以应用程序或库的名称、域名或公司名来命名。通常根据公约,以全部大写的方式来命名全局变量,这样比较显眼(当然,常量也是这样)。

  这种模式是一种组织代码的命名空间的好方法,不仅可以避免您代码中的命名冲突,并且还可以避免在同一个页面中您的代码和第三方代码之间的命名冲突。

  当然,这样的方式也有一些缺点:

  • 需要输入更多的字符,每个变量和函数前都要附加前缀,总体上增加了需要下载的代码量。
  • 仅有一个全局实例意味着任何部分的代码都可以修改该全局实例。
  • 长嵌套名字意味着更长(更慢)的属性解析查询时间。

  本篇后面介绍的沙箱模式可以解决以上这些缺点。

通用命名空间函数

  由于程序负责性的增加、代码的某些部分被分割成不同的文件,以及使用条件包含语句等多个因素,仅假设您的代码是第一个定义某个命名空间或它内部的属性,这种做法已经变得不再安全。添加到命名空间的一些属性可能已经存在,这导致可能会覆盖它们。因此,在添加一个属性或者创建一个命名空间之前,最好是首先检查它是否已经存在:

// 不安全的代码
var MYAPP = {};
// 更好的代码风格
if(typeof MYAPP === 'undefined') {
var MYAPP = {};
}
// 或者用更短的语句
var MYAPP = MYAPP || {};

  可以看到这些附加的检查是如何循序导致大量的重复代码。比如,如果想要定义MYAPP.modules.module2,必须构造三次检查,每次检查都要针对定义的一个对象或者属性。这也就是为什么需要一个可以很方便地处理命名空间细节的可重用函数的原因。让我们称该函数为namespace()并以如下方式使用:

// 使用命名空间函数
MYAPP.namespace('MYAPP.modules.module2'); // 相当于以下代码
var MYAPP = {
modules:{
module2:{}
}
};

  接下来是一个命名空间函数的示例。这个实现是非破坏性的,也就是说,如果已经存在一个命名空间,便不会再重新创建它:

var MYAPP = MYAPP || {};

MYAPP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP,
i; // 剥离最前面的冗余全局变量
if(parts[0] === "MYAPP"){
parts = parts.slice(1);
} for(i = 0;i < parts.length; i += 1){
// 如果不存在就创建一个属性
if(typeof parent[parts[i]] === 'undefined'){
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
}
// 本实现使下列所有这些用法都能正常运行:
// 将返回值赋给一个全局变量
var module2 = MYAPP.namespace('MYAPP.modules.module2');
console.log(module2 === MYAPP.modules.module2); // 忽略最前面的‘MYAPP’
console.log(MYAPP.namespace('modules.module51')); // 长命名空间
console.log(MYAPP.namespace('once.upon.a.time.there.was.this.long.short.nested.property'));

二、声明依赖关系

  JavaScript库通常是模块化且依据命名空间组织的,这使您能够仅包含所需的模块。例如,在YUI2库中有一个充当命名空间的全局变量YAHOO,而模块是该全局变量的属性,比如YAHOO.util.Dom和YAHOO.util.Event。

  在您的函数或模块顶部声明代码所依赖的模块是一个非常好的主意。该声明仅涉及创建一个局部变量并使其指向所需的模块。

var myFunction = function () {
// 依赖
var event = YAHOO.util.Event,
dom = YAHOO.util.Dom; // 使用事件和DOM变量
// 其他逻辑
};

  这是一个及其简单的模式,但是它却有很多优点:

  • 显式的依赖声明向您代码的用户表明了他们确定需要的特定脚本文件已经包含在该页面中。
  • 在函数顶部的前期声明可以使您很容易地发现并解析依赖。
  • 解析局部变量的速度总是要比解析全局变量要快,甚至比使用全局变量的嵌套属性还要快,这导致了更好的性能。当使用这种依赖声明模式时,全局符号解析仅会在函数中执行一次。在此之后将会使用局部变量,这种解析速度也快很多。
  • 类似于YUICompressor和Google闭包编译器的这些高级小工具可以重命名局部变量(即,压缩),这导致了更小的代码量,但是这些工具从不会对全局变量进行重命名,因为这样做是不安全的。

  

  这篇就到这里了,说实话就是很小的两个点,但是这两个point,确实会给你的代码带来不错的性能提升。好了,下篇文章见。

《JavaScript 模式》读书笔记(5)— 对象创建模式1的更多相关文章

  1. 《Javascript高级程序设计》读书笔记之对象创建

    <javascript高级程序设计>读过有两遍了,有些重要内容总是会忘记,写一下读书笔记备忘 创建对象 工厂模式 工厂模式优点:有了封装的概念,解决了创建多个相似对象的问题 缺点:没有解决 ...

  2. 设计模式---对象创建模式之原型模式(prototype)

    一:概念 原型模式(Prototype Pattern) 实际上就是动态抽取当前对象运行时的状态 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例.使用Protot ...

  3. C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder

    part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...

  4. 《Javascript模式》之对象创建模式读书笔记

    引言: 在javascript中创建对象是很容易的,可以使用对象字面量或者构造函数或者object.creat.在接下来的介绍中,我们将越过这些方法去寻求一些其他的对象创建模式. 我们知道js是一种简 ...

  5. 《JavaScript 模式》读书笔记(5)— 对象创建模式4

    我们学完了大部分对象创建模式相关的内容,下面还有一些小而精的部分. 七.对象常量 JavaScript中没有常量的概念,虽然许多现代的编程环境可能为您提供了用以创建常量的const语句.作为一种变通方 ...

  6. 《JavaScript模式》第5章 对象创建模式

    @by Ruth92(转载请注明出处) 第5章:对象创建模式 JavaScript 是一种简洁明了的语言,并没有其他语言中经常使用的一些特殊语法特征,如 命名空间.模块.包.私有属性 以及 静态成员 ...

  7. 深入理解JavaScript系列(47):对象创建模式(上篇)

    介绍 本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式1:命名空间(namespace) 命名空间可以减少全局命名所需的数量,避免命名冲突或过度. ...

  8. 深入理解JavaScript系列(48):对象创建模式(下篇)

    介绍 本篇主要是介绍创建对象方面的模式的下篇,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式6:函数语法糖 函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用pro ...

  9. 设计模式---对象创建模式之构建器模式(Builder)

    一:概念 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象 ...

随机推荐

  1. 成为数据专家,你只差一个Quick Insights的距离

    身处如今的大数据时代,你真的知道如何处理数据和分析数据吗?或许那些被你忽视的数据背后就暗藏着重要的商业灵感.并非人人都是数据专家,有时候你需要一些专业的软件来帮你处理数据.那么如何能快速.准确地从数据 ...

  2. 【译文】使用webpack提高网页性能优化

    这篇文章原文来自https://developers.google.com/web/fundamentals/performance/webpack/. 说是译文其实更像是笔者做的笔记,如有错误之处请 ...

  3. 新浪微博PC端登录分析

    本来给自己定了个2018的目标,平均每月写两篇文章,现在已经快三月了,第一篇稿子才憋出来,惭愧呀,直入主题吧,今天给大家带来的是新浪微博PC端的模拟登陆. 工具 这次使用的工具是Charles和chr ...

  4. CountDownLatch源码探究 (JDK 1.8)

    CountDownLatch能够实现让线程等待某个计数器倒数到零的功能,之前对它的了解也仅仅是简单的使用,对于其内部如何实现线程等待却不是很了解,最好的办法就是通过看源码来了解底层的实现细节.Coun ...

  5. 软件工程实验一 Git代码版本管理

    实验一  GIT 代码版本管理 一.实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2)熟练掌握git的基本指令和分支管理指令: 二.实验内容: 1)安装git: 2)初始配置git ,gi ...

  6. Manjaro 19.01 kde下Tim sogou软件安装问题及解决

    我的系统配置 首先第一个问题是,在manjaro下Tim Thunderspeed这种deepin-wine的软件.今天我在装这些软件的时候,安装之后不能打开,闪退.苦恼了我好一会儿.终于找到了解决的 ...

  7. 为什么要使用webpack?

    在网页中会引用到哪些常见的静态资源? js (.js  .jsx  .coffee  .ts) css (.css  .less  .sass  .scss scss是sass的plus版) imag ...

  8. 编程老司机带你玩转 CompletableFuture 异步编程

    本文从实例出发,介绍 CompletableFuture 基本用法.不过讲的再多,不如亲自上手练习一下.所以建议各位小伙伴看完,上机练习一把,快速掌握 CompletableFuture. 个人博文地 ...

  9. 阿里云上docker部署nginx实现反向代理

    简介   需要从镜像仓库找到所需要的nginx版本pull下来.(地址:https://hub.docker.com/) 1.docker pull nginx 1.挂载目录 1.1 获取nginx. ...

  10. 玩转 .NET Core 3.0:逐浪CMS新版发布,建站更简单、网站更安全

    2019年11月11日,在大家都忙于网上体会“双11 ”的热闹气氛的时候,逐浪CMS开发者团队正在做着新版本发布的最后工作.此次更新是基本于 .NET Core 3.0开发,也是全国首个基于 .NET ...