《JavaScript 模式》读书笔记(5)— 对象创建模式1
这又是一个新的开始,对象的重要性不言而喻。在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的更多相关文章
- 《Javascript高级程序设计》读书笔记之对象创建
<javascript高级程序设计>读过有两遍了,有些重要内容总是会忘记,写一下读书笔记备忘 创建对象 工厂模式 工厂模式优点:有了封装的概念,解决了创建多个相似对象的问题 缺点:没有解决 ...
- 设计模式---对象创建模式之原型模式(prototype)
一:概念 原型模式(Prototype Pattern) 实际上就是动态抽取当前对象运行时的状态 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例.使用Protot ...
- C++设计模式 之 “对象创建”模式:Factory Method、Abstract Factory、Prototype、Builder
part 0 “对象创建”模式 通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式 Fact ...
- 《Javascript模式》之对象创建模式读书笔记
引言: 在javascript中创建对象是很容易的,可以使用对象字面量或者构造函数或者object.creat.在接下来的介绍中,我们将越过这些方法去寻求一些其他的对象创建模式. 我们知道js是一种简 ...
- 《JavaScript 模式》读书笔记(5)— 对象创建模式4
我们学完了大部分对象创建模式相关的内容,下面还有一些小而精的部分. 七.对象常量 JavaScript中没有常量的概念,虽然许多现代的编程环境可能为您提供了用以创建常量的const语句.作为一种变通方 ...
- 《JavaScript模式》第5章 对象创建模式
@by Ruth92(转载请注明出处) 第5章:对象创建模式 JavaScript 是一种简洁明了的语言,并没有其他语言中经常使用的一些特殊语法特征,如 命名空间.模块.包.私有属性 以及 静态成员 ...
- 深入理解JavaScript系列(47):对象创建模式(上篇)
介绍 本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式1:命名空间(namespace) 命名空间可以减少全局命名所需的数量,避免命名冲突或过度. ...
- 深入理解JavaScript系列(48):对象创建模式(下篇)
介绍 本篇主要是介绍创建对象方面的模式的下篇,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式6:函数语法糖 函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用pro ...
- 设计模式---对象创建模式之构建器模式(Builder)
一:概念 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象 ...
随机推荐
- [python每日一练]--0012:敏感词过滤 type2
题目链接:https://github.com/Show-Me-the-Code/show-me-the-code代码github链接:https://github.com/wjsaya/python ...
- gcc编译器常用选项的含义
-w: 关闭编译时的警告, 也就是编译后不显示任何warning,因此有时编译中会出现一些诸如数据转换之类的可忽略警告, -Wall: 显示编译后所有警告 -W: 显示警告,但是只是显示编译器认为的会 ...
- java反序列化-ysoserial-调试分析总结篇(2)
前言: 这篇主要分析commonCollections2,调用链如下图所示: 调用链分析: 分析环境:jdk1.8.0 反序列化的入口点为src.zip!/java/util/PriorityQueu ...
- 成长日记(2) Java面向对象
本篇主要是记录自己在学习路上的笔记,如果有哪里记错了请大家直接指出 面向对象的概念 *人为抽象的一种编程模型 *面向过程 代码集中 难以维护 *类:对事物 算法 逻辑 概念等的抽象 理解成 模板 图纸 ...
- 性能测试之Mysql数据库调优
一.前言 性能调优前提:无监控不调优,对于mysql性能的监控前几天有文章提到过,有兴趣的朋友可以去看一下 二.Mysql性能指标及问题分析和定位 1.我们在监控图表中关注的性能指标大概有这么几个:C ...
- 浅谈C# Dictionary实现原理
使用C#已经有好多年头了,然后突然有一天被问到C#Dictionary的基本实现,这让我反思到我一直处于拿来主义,能用就好,根本没有去考虑和学习一些底层架构,想想令人头皮发麻.下面开始学习一些我平时用 ...
- 前端性能优化之 Composite
摘要: 一个 Web 页面的展示,简单来说可以认为经历了 JavaScript/Style/Layout/Paint/Composite 几个步骤.本文主要深入 Composite 部分,从渲染原理. ...
- 第十章、Vue项目的联调上线
抓包 Fiddler 一.解决跨域 proxyTable(查看博客总结) 二.解决用本机ip地址不能访问 在dev中加上 --host 0.0.0.0就可以用本机ip访问,这样的话可以用手机在内网(局 ...
- frida入门总结
一.Frida概述 Frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等. frida分为两部分,服务端运行在目标机上,通过注入进程的方式来 ...
- 安装msyql报错——error: Failed dependencies
报错原因: 1.存在两个版本的msyql-community-release. 解决方法: 1.将不要的哪个进行去除,使用命令: rpm -e --nodeps mysql80-community-r ...