《JavaScript面向对象编程指南》——1.5 面向对象的程序设计

简介:

本节书摘来自异步社区《JavaScript面向对象编程指南》一书中的第1章,第1.5节,作者: 【加】Stoyan Stefanov 译者: 凌杰 更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.5 面向对象的程序设计

在我们深入学习JavaScript之前,首先要了解一下“面向对象”的具体含义,以及这种程序设计风格的主要特征。下面我们列出了一系列在面向对象程序设计(OOP)中最常用到的概念:

对象、方法、属性

封装
聚合
重用与继承
多态
现在,让我们来进行逐一阐述。

1.5.1 对象
既然这种程序设计风格叫做面向对象,那么它的重点就在于对象。而所谓的对象,实质上是指“事物”(包括人和物)在程序设计语言中的表现形式。这里的“事物”可以是任何东西(如某个客观存在的对象,或者某些较为抽象的概念)。例如,对于猫这种常见对象来说,我们可以看到它们具有某些明确的特征(如颜色、名字、体型等),能执行某些动作(如喵喵叫、睡觉、躲起来、逃跑等)。在OOP语义中,这些对象特征就叫做属性,而那些动作就称之为方法。

此外,我们还有一个口语方面的类比1:

对象往往是用名词来表示的(如book、person)
方法一般都是些动词(如read、run)
属性值则往往是一些形容词
我们可以来试一下。例如,在“The black cat sleeps on my head”这个句子中,“the cat”(名词)就是一个对象,“black”(形容词)则是一个颜色属性值,而“sleep”(动词)则代表一个动作,也就是OOP语义中的方法。甚至,为了进一步证明这种类比的合理性,我们也可以将句子中的“on my head”看做动作“sleep”的一个限定条件,因此,它也可以被当做传递给sleep方法的一个参数。

1.5.2 类
在现实生活中,相似的对象之间往往都有一些共同的组成特征。例如蜂鸟和老鹰都具有鸟类的特征,因此它们可以被统称为鸟类。在OOP中,类实际上就是对象的设计蓝图或者制作配方。“对象”这个词,我们有时候也叫做“实例”,所以我们可以说老鹰是鸟类的一个实例2。我们能基于相同的类创建出许多不同的对象。因为类更多的是一种模板,而对象就是在这些模板的基础上被创建出来的。

但是我们要明白,JavaScript与C++或Java这种传统的面向对象语言不同,它实际上压根儿没有类。该语言的一切都是基于对象的,其所依靠的是一套原型系统(这里的原型(prototype)实际上也是一种对象,我们稍后再来详细讨论这个问题)。在传统的面向对象语言中,我们一般会这样描述自己的做法:“我基于Person类创建了一个叫做Bob的新对象。”,而在这种基于原型的面向对象语言中,我们则会这样描述:“我将现有的Person对象扩展成了一个叫做Bob的新对象。”

1.5.3 封装
封装则是另一个OOP相关的概念,它主要用于阐述对象中所包含(或封装)的内容,它们通常由两部分组成:

相关的数据(用于存储属性)。
基于这些数据所能做的事(所能调用的方法)。
但除此之外,封装这个术语中还包含了一层隐藏信息的概念,这完全是另一方面的问题。因此,我们在理解这个概念时,必须要留意它在具体的OOP语境中的含义。

以一个MP3播放器为例。如果假设这是一个对象,那么作为该对象的用户,我们无疑需要一些类似于像按钮、显示屏这样的工作接口。这些接口能帮助我们使用该对象(如播放歌曲之类)。至于它们内部是如何工作的,我们并不清楚,而且多数情况下也不会在乎这些。换句话说,这些接口的实现对我们来说是不可见的。同样的,在OOP中也是如此。当我们在代码中调用一个对象的方法时,无论该对象是来自我们自己的实现还是某个第三方库,我们都不需要知道该方法是如何工作的。在编译型语言中,我们甚至都无法查看这些对象的工作代码。而由于JavaScript是一种解释型语言,源代码是可以查看的。但至少在这个概念上它们是一致的,即我们只需要知道所操作对象的接口,而不必去关心它的具体实现。

关于信息隐藏,还有另一方面内容,即方法与属性的可见性。在某些语言中,我们能通过public、private、protected这些关键字来限定方法和属性的可见性。这种限定分类定义了对象用户所能访问的层次。例如,private方法只有其所在对象内部的代码才有权访问,而public方法则是任何人都能访问的。在JavaScript中,尽管所有的方法和属性都是public的,但是我们将会看到,该语言还是提供了一些隐藏数据的方法,以保护程序的隐密性。

1.5.4 聚合
所谓聚合,有时候也叫做组合,实际上是指我们将几个现有对象合并成一个新对象的过程。总之,这个概念所强调的就是这种将多个对象合而为一的能力。通过聚合这种强有力的方法,我们可以将一个问题分解成多个更小的问题。这样一来,问题就会显得更易于管理(便于我们各个击破)。当一个问题域的复杂程度令我们难以接受时,我们就可以考虑将它分解成若干子问题区,并且必要的话,这些问题区还可以再继续分解成更小的分区。这样做有利于我们从几个不同的抽象层次来考虑这个问题。例如,个人电脑是一个非常复杂的对象,我们不可能知道它启动时所发生的全部事情。但如果我们将这个问题的抽象级别降低到一定的程度,只关注它几个组件对象的初始化工作,例如监视器对象、鼠标对象、键盘对象等,我们就很容易深入了解这些子对象情况,然后再将这些部分的结果合并起来,之前那个复杂问题就迎刃而解了。

我们还可以找到其他类似情况,例如Book是由一个或多个author对象、publisher对象、若干chapter对象以及一组table对象等合并(聚合)而成的对象。

1.5.5 继承
通过继承这种方式,我们可以非常优雅地实现对现有代码的重用。例如,我们有一个叫做Person的一般性对象,其中包含一些姓名、出生日期之类的属性,以及一些功能性函数,如步行、谈话、睡觉、吃饭等。然后,当我们发现自己需要一个Programmer对象时,当然,这时候你可以再将Person对象中所有的方法与属性重新实现一遍,但除此之外还有一种更聪明的做法,即我们可以让Programmer继承自Person,这样就省去了我们不少工作。因为Programmer对象只需要实现属于它自己的那部分特殊功能(例如“编写代码”),而其余部分只需重用Person的实现即可。

在传统的OOP环境中,继承通常指的是类与类之间的关系,但由于JavaScript中不存在类,因此继承只能发生在对象之间。

当一个对象继承自另一个对象时,通常会往其中加入新的方法,以扩展被继承的老对象。我们通常将这一过程称之为“B继承自A”或者“B扩展自A”。另外对于新对象来说,它也可以根据自己的需要,从继承而来那组方法中选择几个来重新定义。这样做并不会改变对象的接口,因为方法的名字是相同的,只不过当我们调用新对象时,该方法的行为与之前不同了。我们将这种重定义继承方法的过程叫做覆写。

1.5.6 多态
在之前的例子中,我们的Programmer对象继承了上一级对象Person的所有方法。这意味着这两个对象都实现了“talk”等方法。现在,我们的代码中有一个叫做Bob的变量,即便是在我们不知道它是一个Person对象还是一个Programmer对象情况下,也依然可以直接调用该对象的“talk”方法,而不必担心这会影响代码的正常工作。类似这种不同对象通过相同的方法调用来实现各自行为的能力,我们就称之为多态。

相关文章
|
7月前
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(三)
深入JS面向对象(原型-继承)
54 0
|
7月前
|
JavaScript 前端开发 Java
深入JS面向对象(原型-继承)(一)
深入JS面向对象(原型-继承)
62 0
|
2月前
|
JavaScript 前端开发 Java
JavaScript中的面向对象编程(OOP) - 终极指南
本文介绍了 JavaScript 的面向对象编程 (OOP) 概念,包括继承、多态、封装和抽象等关键要素,并通过代码示例帮助开发者理解和应用 OOP 思维。
38 5
|
3月前
|
JavaScript 前端开发 Java
js面向对象编程|24
js面向对象编程|24
|
4月前
|
存储 JavaScript 算法
JS程序设计的常用套路
亲尝百草,方知甘苦。套路,通常有助于提升代码的可读性、扩展性和效率。以下是作者工作中总结出来的一部分代码套路,分享给大家。
|
6月前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
140 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
6月前
|
JavaScript 前端开发 Java
使用JavaScript进行面向对象编程的指南
使用JavaScript进行面向对象编程的指南
37 4
|
6月前
|
前端开发 JavaScript 安全
TypeScript作为一种静态类型的JavaScript超集,其强大的类型系统和面向对象编程特性为微前端架构的实现提供了有力的支持
【6月更文挑战第11天】微前端架构借助TypeScript提升开发效率和代码可靠性。 TypeScript提供类型安全,防止微前端间通信出错;智能提示和自动补全加速跨代码库开发;重构支持简化代码更新。通过定义公共接口确保一致性,用TypeScript编写微前端以保证质量。集成到构建流程确保顺利构建打包。在微前端场景中,TypeScript是强有力的语言选择。
49 2
|
7月前
|
前端开发 JavaScript
前端 JS 经典:Class 面向对象
前端 JS 经典:Class 面向对象
39 1
|
6月前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
54 0