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

相关文章
|
设计模式 Java 数据库连接
【设计模式】【创建型模式】工厂方法模式(Factory Methods)
一、入门 什么是工厂方法模式? 工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定实例化哪个类。工厂方法模式使类的实例化延迟
470 16
|
设计模式 负载均衡 监控
并发设计模式实战系列(2):领导者/追随者模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第二章领导者/追随者(Leader/Followers)模式,废话不多说直接开始~
495 0
|
设计模式 监控 Java
并发设计模式实战系列(1):半同步/半异步模式
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发设计模式实战系列,第一章半同步/半异步(Half-Sync/Half-Async)模式,废话不多说直接开始~
699 0
|
设计模式 安全 Java
并发设计模式实战系列(12):不变模式(Immutable Object)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第十二章,废话不多说直接开始~
418 0
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
1113 11
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
JavaScript 前端开发 Docker
如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
通过这些步骤,可以确保您的Next.js应用在多核服务器上高效运行,并且在Docker环境中实现高效的容器化管理。
1788 44
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
440 40
|
设计模式 Java 关系型数据库
设计模式:工厂方法模式(Factory Method)
工厂方法模式是一种创建型设计模式,通过将对象的创建延迟到子类实现解耦。其核心是抽象工厂声明工厂方法返回抽象产品,具体工厂重写该方法返回具体产品实例。适用于动态扩展产品类型、复杂创建逻辑和框架设计等场景,如日志记录器、数据库连接池等。优点包括符合开闭原则、解耦客户端与具体产品;缺点是可能增加类数量和复杂度。典型应用如Java集合框架、Spring BeanFactory等。
|
设计模式 Prometheus 监控
并发设计模式实战系列(20):扇出/扇入模式(Fan-Out/Fan-In)(完结篇)
🌟 大家好,我是摘星!🌟今天为大家带来的是并发设计模式实战系列,第二十章,废话不多说直接开始~
534 0

热门文章

最新文章