💜《JavaScript 语言精粹》之继承篇

106 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

……往往会把一件完整的东西化成无数的形象。就想凹凸镜一般,从正面望去,只见一片模糊。 —— 威廉 · 莎士比亚,《查理二世》(The Tragedy of King Richard the Second)

首先,它是代码重用的一种形式,因为它们可以显著地减少软件开发的成本

其次是引入了一套类型系统的规范,因为类型转换会丧失类型系统在安全上的优势。

JavaScript 是一门弱类型语言,从不需要类型转换。对象继承关系变得无关紧要。对于一个对象来说重要的是它能做什么,而不是它从哪里来。

JavaScript 提供了一套更为丰富的代码重用模式。它可以模拟那些基于类的模式,同时它也可以支持其他更具表现力的模式。在 JavaScript 中可能的继承模式有很多。在本章中,我们将研究几种最为直接的模式。

5.1 伪类

JavaScript 的原型存在着诸多矛盾。它的某些复杂的语言看起来就像那些基于类的语言,这些语法问题掩盖了它的原型机制。它不直接让对象从其他对象继承,反而插入了一个多余的间接层:通过构造器函数产生对象。

当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的一些代码:

this.prototype = { constructor: this };
  • 新函数对象被赋予一个prototype属性,它的值是一个包含constructor属性且属性值为该新函数的对象。这个prototype对象是存放继承特征的地方;
  • 当采用构造器调用模式,即用new前缀去调用一个函数时,函数执行的方式会被修改。
  • 伪类模式本意是想向面向对象靠拢,但它看起来格格不入。
  • 使用构造器函数存在一个严重的危害。如果你在调用构造器函数时忘记了在前面加上new前缀,那么this将不会绑定到一个新对象上。

5.2 对象说明符

有时候,构造器要接受一大串参数。如果我们在编写构造器时让它接受一个简单的对象说明符,可能会更加友好。

// 与其这样写
var myObject = maker(f, l, m, c, s)
// 不如这样写
var myObject = maker({
	first: f,
	middle: m,
	last: l,
	state: s,
	city: c
})

现在多个参数按任何顺序排列,如果构造器会聪明地使用默认值,一些参数可以忽略掉,并且代码也更容易阅读。

当与JOSN一起工作时,这种形式还可以有一个间接的好处。如果构造器去的一个对象说明符,就能让它轻松实现,因为我们可以简单地把JOSN对象传递给构造器,而它将返回一个构造完全的对象。

5.3 原型

  • 一个新对象可以继承一个旧对象的属性。

  • 你通过构造一个有用的对象开始,接着可以构造更多和那个对象类似的对象。这就可以完全避免把一个应用拆解成一系列嵌套抽象类的分类过程

5.4 函数化

  • 函数化模式有很大的灵活性。它相比伪类模式不仅带来的工作更少,还让我们得到更好的封装和信息隐藏,以及访问父类方法的能力

  • 如果我们用函数化的样式创建一个对象,并且该对象的所有方法都不使用thisthat,那么该对象就是持久性的。一个持久性对象就是一个简单功能函数的集合。

  • 一个持久性的对象不会被入侵。访问一个持久性的对象时,除非有方法授权,否则攻击者不能访问对象的内部状态。

5.5 部件

  • 我们可以从一套部件中把对象组装出来;例如,我们可以构造一个给任何对象添加简单事件处理特性的函数。

  • 一个构造器函数可以从一套部件中把对象组装出来。