这里介绍下面这4种设计模式

  • Module
  • Prototype
  • Observer
  • Singleton

每种模式有许多属性构成,在这我只强调以下几点:

1 Context: 在何种情况使用哪种模式?

2 问题: 我们要解决什么为题?

3 解决方案: 怎么用模式解决我们的问题?

4 实现: 怎么实现这些模式?

Module

module是JavaScript里面的类。类的一个优点是封装--使得某些状态和行为不被其他的类访问. Module设计模式允许我们有私有成员和公共成员。

Module应该是IIFE(Immediately-Invoked-Function-Expressions)这样我们就能有私有作用域-它通过闭包来保护其中的私有成员(Module返回的是一个object而不是一个function).

他应该类似于下面的样子:

(function() {
// 在此声明私有变量或者函数 return {
// 在此声明公共变量或者函数
} })();

在return一个对象之前我们声明了些变量和函数. 外部的代码无法方位我们的私有变量或函数,因为他们不在一个作用域。下面我们看一个更具体一些的例子:

var HTMLChanger = (function() {
var contents = 'contents' var changeHTML = function() {
var element = document.getElementById('attribute-to-change');
element.innerHTML = contents;
} return {
callChangeHTML: function() {
changeHTML();
console.log(contents);
}
}; })(); HTMLChanger.callChangeHTML(); // Outputs: 'contents'
console.log(HTMLChanger.contents); // undefined

注意callChangeHTML绑定在返回的对象里面,能在HTMLChanger命名空间中被引用。然而在此module外,contents是不能被访问的。

Revealing Module

Revealing是Module模式的一个变种。 目的是维持封装并且通过返回的对象字面量暴露一些变量和方法。他应该类似于下面的样子:

var Exposer = (function() {
var privateVariable = 10; var privateMethod = function() {
console.log('Inside a private method!');
privateVariable++;
} var methodToExpose = function() {
console.log('This is a method I want to expose!');
} var otherMethodIWantToExpose = function() {
privateMethod();
} return {
first: methodToExpose,
second: otherMethodIWantToExpose
};
})(); Exposer.first(); // Output: This is a method I want to expose!
Exposer.second(); // Output: Inside a private method!
Exposer.methodToExpose; // undefined

Prototype

为了克隆一个对象必须先要有一个用力实例化对象的构造函数。 然后通过关键字prototype来将变量和方法绑定到对象结构中。看看下面的例子:

var TeslaModelS = function() {
this.numWheels = 4;
this.manufacturer = 'Tesla';
this.make = 'Model S';
} TeslaModelS.prototype.go = function() {
// Rotate wheels
} TeslaModelS.prototype.stop = function() {
// Apply brake pads
}

当创建了一个TeslaModelS对象,他会保持构造函数里面初始化的状态。可以通过另外一个方法在prototype上扩展功能:

var TeslaModelS = function() {
this.numWheels = 4;
this.manufacturer = 'Tesla';
this.make = 'Model S';
} TeslaModelS.prototype = {
go: function() {
// Rotate wheels
},
stop: function() {
// Apply brake pads
}
}

Revealing Prototype

var TeslaModelS = function() {
this.numWheels = 4;
this.manufacturer = 'Tesla';
this.make = 'Model S';
} TeslaModelS.prototype = function() { var go = function() {
// Rotate wheels
}; var stop = function() {
// Apply brake pads
}; return {
pressBrakePedal: stop,
pressGasPedal: go
} }();

Observer

我们经常会遇到这样的情况当一个应用的某部分发生了改变的时候,该应用的其他部分需要被更新。在AngularJS中如果$scope对象更新了,一个事件将会被触发通知到其他的组件。观察者模式就是用来干这个事情的。

另一个例子是model-view-controller(MVC)架构;当model更新了,view会发生变化。

var Subject = function() {
this.observers = []; return {
subscribeObserver: function(observer) {
this.observers.push(observer);
},
unsubscribeObserver: function(observer) {
var index = this.observers.indexOf(observer);
if(index > -1) {
this.observers.splice(index, 1);
}
},
notifyObserver: function(observer) {
var index = this.observers.indexOf(observer);
if(index > -1) {
this.observers[index].notify(index);
}
},
notifyAllObservers: function() {
for(var i = 0; i < this.observers.length; i++){
this.observers[i].notify(i);
};
}
};
}; var Observer = function() {
return {
notify: function(index) {
console.log("Observer " + index + " is notified!");
}
}
} var subject = new Subject(); var observer1 = new Observer();
var observer2 = new Observer();
var observer3 = new Observer();
var observer4 = new Observer(); subject.subscribeObserver(observer1);
subject.subscribeObserver(observer2);
subject.subscribeObserver(observer3);
subject.subscribeObserver(observer4); subject.notifyObserver(observer2); // Observer 2 is notified! subject.notifyAllObservers();
// Observer 1 is notified!
// Observer 2 is notified!
// Observer 3 is notified!
// Observer 4 is notified!

Singleton

var printer = (function () {

  var printerInstance;

  function create () {

    function print() {
// underlying printer mechanics
} function turnOn() {
// warm up
// check for paper
} return {
// public + private states and behaviors
print: print,
turnOn: turnOn
};
} return {
getInstance: function() {
if(!printerInstance) {
printerInstance = create();
}
return printerInstance;
}
}; function Singleton () {
if(!printerInstance) {
printerInstance = intialize();
}
}; })(); var officePrinter = printer.getInstance();

[译]你应该知道的4种JavaScript设计模式的更多相关文章

  1. 每个IT安全专业人员应该知道的12种根本漏洞

    每个IT安全专业人员应该知道的12种根本漏洞 每年,IT安全专业人员都面临着数千个新的软件漏洞和数百万个不同的恶意软件程序,但只有12种根本漏洞会让这些软件漏洞和恶意软件程序攻击你的设备.了解这些根本 ...

  2. [译] 你该知道的javascript作用域 (javascript scope)(转)

    javascript有一些对于初学者甚至是有经验的开发者都难以理解的概念. 这个部分是针对那些听到 : 作用域, 闭包, this, 命名空间, 函数作用域, 函数作用域, 全局作用域, 变量作用域( ...

  3. 23种JavaScript设计模式

    原文链接:https://boostlog.io/@sonuton/23-javascript-design-patterns-5adb006847018500491f3f7f 转自: https:/ ...

  4. 21种JavaScript设计模式最新记录(含图和示例)

    最近观看了<Javascript设计模式系统讲解与应用>教程,对设计模式有了新的认识,特在此做些记录. 一.UML 文中会涉及众多的UML类图,在开篇需要做点基础概念的认识.以下面的图为例 ...

  5. 2018年你需要知道的13个JavaScript工具库

    译者按: 你可能已经用到Underscore或者Lodash.本文列举了13个常用的JavaScript工具库来提高开发效率. 原文: 11 Javascript Utility Libraries ...

  6. 你应该知道的25道Javascript面试题

    题目来自 25 Essential JavaScript Interview Questions.闲来无事,正好切一下. 一 What is a potential pitfall with usin ...

  7. 早该知道的7个JavaScript技巧

    我写JavaScript代码已经很久了,都记不起是什么年代开始的了.对于JavaScript这种语言近几年所取得的成就,我感到非常的兴奋:我很幸运也是这些成就的获益者.我写了不少的文章,章节,还有一本 ...

  8. 你有必要知道的 25 个 JavaScript 面试题

    1.使用 typeof bar === "object" 推断 bar 是不是一个对象有神马潜在的弊端?怎样避免这样的弊端? 使用 typeof 的弊端是显而易见的(这样的弊端同使 ...

  9. 早该知道的 7 个JavaScript 技巧[转]

    简洁写法 对象的简写在过去,如果你想创建一个对象,你需要这样: var car = new Object();  car.colour = 'red';  car.wheels = 4;  car.h ...

随机推荐

  1. C语言运算符优先级

    优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 -- () 圆括号 (表达式)/函数名(形参表) -- . 成员选择(对象) 对象.成员名 -- ...

  2. ERROR: Unable to globalize '/usr/local/NONE/etc/php-fpm.d/*.conf' 问题的解决

    今天继续作大死,趟php7的配置的坑. 照例,安装了昨天的各种扩展之后,解压php7的压缩文件到 /usr/local/. 然后开始配置config的扩展: ./configure --prefix= ...

  3. Torch7在Ubuntu下的安装与配置

    Torch7的本系列教程的主要目的是介绍Torch的入门使用.今天首先分享一下Torch7的安装.(在Ubuntu14.04安装torch7) 为什么选择Torch Torch的目标是在建立科学算法的 ...

  4. 纯css3图片旋转展示

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  5. [转]实现一个无法被继承的C++类

    From:http://blog.csdn.net/lazy_tiger/article/details/2224899 一个类不能被继承,也就是说它的子类不能构造父类,这样子类就没有办法实例化整个子 ...

  6. JavaScript自动生成博文目录导航

    转载于:JavaScript自动生成博文目录导航 我们在写博客的时候,如果博文里面有目录,会给人结构清晰.一种一目了然的感觉,看目录就知道这篇博文要讲解的内容,并且点击目录标题就可以跳转到 具体的内容 ...

  7. C++ 使用ifstream读取数据,多读最后一行问题解决方法

    C++文件读取时有一个bug,就是使用eof()判断文件结尾并不准确,最后一行会重复读取一次,可采用以下方法避免重复读取: while (!inFile.eof()) { inFile >> ...

  8. IT培训行业揭秘(四)

    IT培训班的老师前面已经说过,很多都是从一线程序员岗位转过来的,因为培训行业的收入整体上来看还是比作普通程序员要高一些,这是市场的普遍行情.还有一部分老师从培训班学习过并且留到培训班任教的.一般这种老 ...

  9. 酷酷的mapv

    做城市热力图的时候无意浏览到mapv强大的功能.比如地图上路线的汇聚效果,如下 <!DOCTYPE html> <html> <head> <meta cha ...

  10. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...