开启掘金成长之旅!这是我参与「掘金日新计划 · 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 函数化
-
函数化模式有很大的灵活性。它相比伪类模式不仅带来的工作更少,还让我们得到更好的封装和信息隐藏,以及访问父类方法的能力。
-
如果我们用函数化的样式创建一个对象,并且该对象的所有方法都不使用
this或that,那么该对象就是持久性的。一个持久性对象就是一个简单功能函数的集合。 -
一个持久性的对象不会被入侵。访问一个持久性的对象时,除非有方法授权,否则攻击者不能访问对象的内部状态。
5.5 部件
-
我们可以从一套部件中把对象组装出来;例如,我们可以构造一个给任何对象添加简单事件处理特性的函数。
-
一个构造器函数可以从一套部件中把对象组装出来。