《JavaScript设计模式》——第9章 JavaScript设计模式9.1 Constructor(构造器)模式

第9章 JavaScript设计模式

在本章中,我们将探索一些经典与现代设计模式的JavaScript实现。

开发人员通常想知道他们是否应该在工作中使用一种“理想”的模式或模式集。这个问题没有明确的唯一答案,我们研究的每个脚本和 Web 应用程序可能都有它自己的个性化需求,我们需要思考模式的哪些方面能够为实现提供实际价值。

例如,一些项目可能会受益于观察者模式提供的解耦好处(这可以减少应用程序的某些部分对彼此的依赖度),而有些项目可能只是因为太小,而根本无需考虑解耦。

也就是说,一旦我们牢牢掌握了设计模式和与它们最为相配的具体问题,那么将它们集成到我们的应用程序架构中就会变得更加容易。

在本节中将要探索的模式包括:

Constructor(构造器)模式;
Module(模块)模式;
Revealing Module(揭示模块)模式;
Singleton(单例)模式;
Observer(观察者)模式;
Mediator(中介者)模式;
Prototype(原型)模式;
Command(命令)模式;
Facade(外观)模式;
Factory(工厂)模式;
Mixin(混入)模式;
Decorator(装饰者)模式;
Flyweight(享元)模式。

9.1 Constructor(构造器)模式

在经典面向对象编程语言中,Constructor是一种在内存已分配给该对象的情况下,用于初始化新创建对象的特殊方法。在JavaScript中,几乎所有东西都是对象,我们通常最感兴趣的是object构造器。

Object构造器用于创建特定类型的对象—准备好对象以备使用,同时接收构造器可以使用的参数,以在第一次创建对象时,设置成员属性和方法的值(见图9-1)。

9.1.1 对象创建
在JavaScript中,创建新对象的两种常用方法如下所示:

//下面每种方式都将创建一个新的空对象

var newObject = {};

// object构造器的简洁记法

var newObject = new Object();

在Object构造器为特定的值创建对象封装,或者没有传递值时,它将创建一个空对象并返回它。

有四种方法可以将键值赋值给一个对象:

// ECMAScript 3兼容方式
// 1. “点”语法
// 设置属性

newObject.someKey = "Hello World";

// 获取属性

var key = newObject.someKey;

// 2. 中括号语法
// 设置属性

newObject["someKey"] = "Hello World";

// 获取属性

var key = newObject["someKey"];

// 只适用ECMAScript 5 的方式
// 3. Object.defineProperty
// 设置属性

Object.defineProperty(newObject, "someKey", {
     value: "for more control of the property's behavior",
     writable: true,
     enumerable: true,
     configurable: true
});

// 如果上面的看着麻烦,可以使用下面的简便方式

var defineProp = function (obj, key, value) {
  config.value = value;
  Object.defineProperty(obj, key, config);
};

// 使用上述方式,先创建一个空的person对象

var person = Object.create(null);

// 然后设置各个属性

defineProp(person, "car", "Delorean");
defineProp(person, "dateOfBirth", "1981");
defineProp(person, "hasBeard", false);

//4.Object.defineProperties
// 设置属性

Object.defineProperties(newObject, {
   "someKey": {
     value: "Hello World",
     writable: true
    },
    "anotherKey": {
      value: "Foo bar",
      writable: false
    }
});

// 可以用1和2中获取属性的方式获取3和4方式中的属性
正如我们将在本书稍后看到的,这些方法甚至可以用于继承,如下所示:

// 用法
// 创建赛车司机driver对象,继承于person对象

var driver = Object.create(person);

// 为driver设置一些属性

defineProp(driver, "topSpeed", "100mph");

// 获取继承的属性

console.log(driver.dateOfBirth);

// 获取我们设置的100mph的属性

console.log(driver.topSpeed);

9.1.2 基本Constructor(构造器)
正如我们在前面所看到的,JavaScript不支持类的概念,但它确实支持与对象一起用的特殊constructor(构造器)函数。通过在构造器前面加 new 关键字,告诉JavaScript像使用构造器一样实例化一个新对象,并且对象成员由该函数定义。

在构造器内,关键字this引用新创建的对象。回顾对象创建,基本的构造器看起来可能是这样的:

function Car(model, year, miles) {
  this.model = model;
  this.year = year;
  this.miles = miles;
  this.toString = function () {
    return this.model + " has done " + this.miles + " miles";
  };
}

// 用法
// 可以创建car的新实例

var civic = new Car("Honda Civic", 2009, 20000);
var mondeo = new Car("Ford Mondeo", 2010, 5000);

// 打开浏览器控制台,查看这些对象上调用的toString()方法的输出

console.log(civic.toString());
console.log(mondeo.toString());

上面是一个简单的构造器模式版本,但它确实有一些问题。其中一个问题是,它使继承变得困难,另一个问题是,toString()这样的函数是为每个使用Car构造器创建的新对象而分别重新定义的。这不是最理想的,因为这种函数应该在所有的Car类型实例之间共享。

值得庆幸的是,因为有很多ES3和ES5兼容替代方法能够用于创建对象,所以很容易解决这个限制问题。

9.1.3 带原型的Constructor(构造器)
JavaScript中有一个名为prototype的属性。调用JavaScript构造器创建一个对象后,新对象就会具有构造器原型的所有属性。通过这种方式,可以创建多个Car对象,并访问相同的原型。因此我们可以扩展原始示例,如下所示:

function Car(model, year, miles) {

  this.model = model;
  this.year = year;
  this.miles = miles;
}

// 注意这里我们使用Object.prototype.newMethod而不是Object.prototype是为了避免重新定义prototype对象

Car.prototype.toString = function () {
  return this.model + " has done " + this.miles + " miles";
};

//用法:

var civic = new Car("Honda Civic", 2009, 20000);
var mondeo = new Car("Ford Mondeo", 2010, 5000);

console.log(civic.toString());
console.log(mondeo.toString());

现在toString()的单一实例就能够在所有Car对象之间共享。

时间: 2024-09-07 20:23:05

《JavaScript设计模式》——第9章 JavaScript设计模式9.1 Constructor(构造器)模式的相关文章

Pro JavaScript Techniques第七章: JavaScript与CSS

  JavaScript和CSS的交互是现代JavaScript程序设计的支柱.事实上对于所有的现代web应用程序来说,至少使用某些形式的动态交互是必须的.那么做过之后,用户可以更快地操作而更少地把时间浪费在等待页面加载上.将动态技术与第六章提出的事件方面的观念相结合,对于实现无缝而强大的用户体验是非常重要的. 层叠式样式表是用来对易用的.有吸引力的网页进行修饰和布局的事实标准,它在给用户提供最少的困难的同时为开发者提供最多的能力.当你将那一能力与JavaScript相结合时,你将能够构造强健的

JavaScript设计模式之工厂模式和构造器模式_javascript技巧

什么是模式 前阵子准备期末考试,劳神又伤身的,实在闲不得空来更新文章,今天和大家说说javascript中的设计模式. 首先呢,我们需要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案. js反模式常见例子 1.向setTimeout和setInterval传递字符串,而不是函数,这会触发eval()的内部使用. 2.在全局上下文中定义大量的变量污染全局命名空间 3.修改Object类的原型 4.以内联形式使用js,嵌入在HTML文件中的js代码是无法包含在外部单元

深入理解JavaScript系列(25):设计模式之单例模式详解

 这篇文章主要介绍了深入理解JavaScript系列(25):设计模式之单例模式详解,本文给出了多种单例模式的实现方式,需要的朋友可以参考下     介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现.OK,正式开始. 在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象.在JavaScript里,单例

深入理解JavaScript系列(26):设计模式之构造函数模式详解

 这篇文章主要介绍了深入理解JavaScript系列(26):设计模式之构造函数模式详解,本文讲解了基本用法.构造函数与原型.只能用new吗?.强制使用new.原始包装函数等内容,需要的朋友可以参考下     介绍 构造函数大家都很熟悉了,不过如果你是新手,还是有必要来了解一下什么叫构造函数的.构造函数用于创建特定类型的对象--不仅声明了使用的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值.你可以自定义自己的构造函数,然后在里面声明自定义类型对象的属性或方法. 基本用法 在

深入理解JavaScript系列(28):设计模式之工厂模式详解

 这篇文章主要介绍了深入理解JavaScript系列(28):设计模式之工厂模式详解,工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类,需要的朋友可以参考下     介绍 与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口方法以便创建的时候指定自己的对象类型. 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于

深入理解JavaScript系列(27):设计模式之建造者模式详解

 这篇文章主要介绍了深入理解JavaScript系列(27):设计模式之建造者模式详解,建造者模式可以将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示,需要的朋友可以参考下     介绍 在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成:由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定.如何应对这种变化?如何提供一种"封装机制"来隔离出"复

深入理解JavaScript系列(29):设计模式之装饰者模式详解

 这篇文章主要介绍了深入理解JavaScript系列(29):设计模式之装饰者模式详解,装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数),需要的朋友可以参考下     介绍 装饰者提供比继承更有弹性的替代方案. 装饰者用用于包装同接口的对象,不仅允许你向方法添加行为,而且还可以将方法设置成原始对象调用(例如装饰者的构造函数). 装饰者用于通过重载方法的形式添加新功能,该模式可以在被装饰者前面或者后面加上自己的行为以达到特定的目的.

深入理解JavaScript系列(30):设计模式之外观模式详解

 这篇文章主要介绍了深入理解JavaScript系列(30):设计模式之外观模式详解,外观模式(Facade)为子系统中的一组接口提供了一个一致的界面,此模块定义了一个高层接口,这个接口值得这一子系统更加容易使用,需要的朋友可以参考下     介绍 外观模式(Facade)为子系统中的一组接口提供了一个一致的界面,此模块定义了一个高层接口,这个接口值得这一子系统更加容易使用. 正文 外观模式不仅简化类中的接口,而且对接口与调用者也进行了解耦.外观模式经常被认为开发者必备,它可以将一些复杂操作封装

深入理解JavaScript系列(31):设计模式之代理模式详解

 这篇文章主要介绍了深入理解JavaScript系列(31):设计模式之代理模式详解,代理模式使得代理对象控制具体对象的引用,代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西,需要的朋友可以参考下     介绍 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 代理模式使得代理对象控制具体对象的引用.代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西. 正文 我们