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

简介:

本节书摘来自异步社区《JavaScript设计模式》一书中的第9章,第9.1节, 作者: 【美】Addy Osmani 译者: 徐涛 更多章节内容可以访问云栖社区“异步社区”公众号查看。

第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)。

screenshot

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对象之间共享。

相关文章
|
11天前
|
设计模式 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 设计模式与实战应用
【4月更文挑战第30天】本文探讨JavaScript设计模式在提升开发效率和代码质量中的关键作用。涵盖单例、工厂、观察者、装饰器和策略模式,并通过实例阐述其在全局状态管理、复杂对象创建、实时数据更新、功能扩展和算法切换的应用。理解并运用这些模式能帮助开发者应对复杂项目,提升前端开发能力。
|
1月前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
22 0
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
54 0
|
29天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
9天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
19 4
|
11天前
|
JavaScript 前端开发 IDE
【JavaScript与TypeScript技术专栏】JavaScript与TypeScript混合编程模式探讨
【4月更文挑战第30天】本文探讨了在前端开发中JavaScript与TypeScript的混合编程模式。TypeScript作为JavaScript的超集,提供静态类型检查等增强功能,但完全切换往往不现实。混合模式允许逐步迁移,保持项目稳定性,同时利用TypeScript的优点。通过文件扩展名约定、类型声明文件和逐步迁移策略,团队可以有效结合两者。团队协作与沟通在此模式下至关重要,确保代码质量与项目维护性。
|
14天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
34 2
|
17天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
17天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
19天前
|
设计模式
设计模式(一)简单工厂模式
设计模式(一)简单工厂模式
14 0