深入理解JavaScript系列(17):面向对象编程之概

在本篇文章,我们考虑在ECMAScript中的面向对象编程的各个方面(虽然以前在许多文章中已经讨论过这个话题)。我们将更多地从理论方面看这些问题。 特别是,我们会考虑对象的创建算法,对象(包括基本关系 - 继承)之间的关系是如何,也可以在讨论中使用(我希望将消除之前对于JavaScript中OOP的一些概念歧义)。

英文原文:

概论、范式与思想

在进行ECMAScript中的OOP技术分析之前,我们有必要掌握一些OOP基本的特征,并澄清概论中的主要概念。

ECMAScript支持包括结构化、面向对象、函数式、命令式等多种编程方式,某些情况下还支持面向方面编程;但本文是讨论面向对象编程,所以来给出ECMAScript中面向对象编程的定义:

ECMAScript是基于原型实现的面向对象编程语言。
基于原型的OOP和基于静态类的方式直接有很多差异。 让我们一起来看看他们直接详细的差异。

基于类特性和基于原型

注意,在前面一句很重要的一点已经指出的那样-完全基于静态类。 随着“静态”一词,我们了解静态对象和静态类,强类型(虽然不是必需的)。

关于这种情况,很多论坛上的文档都有强调这是他们反对将在JavaScript里将“类与原型”进行比较的主要原因,尽管他们在实现上的有所不同(例如基于动态类的Python和Ruby)不是太反对的重点(某些条件写,尽管思想上有一定不同,但JavaScript没有变得那么另类),但他们反对的重点是静态类和动态原型(statics + classes vs. dynamics + prototypes),确切地说,一个静态类(例如:C + +,JAVA)和他的属下及方法定义的机制可以让我们看到它和基于原型实现的准确区别。

但是,让我们来一个一个列举一下。 让我们考虑总则和这些范式的主要概念。

基于静态类

在基于类的模型中,有个关于类和实例的概念。 类的实例也常常被命名为对象或范例 。

类与对象

类代表了一个实例(也就是对象)的抽象。在这方面有点像数学,但我们一把称之为类型(type)或分类(classification)。

例如(这里和下面的例子都是伪代码):

复制代码 代码如下:


C = Class {a, b, c} // 类C, 包括特性a, b, c


实例的特点是:属性(对象描述 )和方法(对象活动)。特性本身也可视为对象:即属性是否可写的,可配置,可设置的(getter/setter)等。因此,对象存储了状态 (即在一个类中描述的所有属性的具体值),类为他们的实例定义了严格不变的结构(属性)和严格不变的行为(方法)。

复制代码 代码如下:


C = Class {a, b, c, method1, method2}
 
c1 = {a: 10, b: 20, c: 30} // 类C是实例:对象с1
c2 = {a: 50, b: 60, c: 70} // 类C是实例:对象с2,拥有自己的状态(也就是属性值)

层次继承

为了提高代码重用,类可以从一个扩展为另一个,在加上额外的信息。 这种机制被称为(分层)继承 。

复制代码 代码如下:


D = Class extends C = {d, e} // {a, b, c, d, e}
d1 = {a: 10, b: 20, c: 30, d: 40, e: 50}

在类的实例上调用方的时候,通常会现在原生类本书就查找该方法,如果没找到就到直接父类去查找,如果还没找到,就到父类的父类去查找(例如严格的继承链上),如果查到继承的顶部还没查到,那结果就是:该对象没有类似的行为,也没办法获取结果。

复制代码 代码如下:


d1.method1() // D.method1 (no) -> C.method1 (yes)
d1.method5() // D.method5 (no) -> C.method5 (no) -> no result


与在继承里方法不复制到一个子类相比,属性总是被复杂到子类里的。 我们可以看到子类D继承自父类C类:属性a,b,c是复制过去了,D的结构是{a, b, c, d, e} } 。然而,方法{method1, method2}是没有复制过去,而是继承过去的。 因此,也就是说如果一个很深层次的类有一些对象根本不需要的属性的话,那子类也有拥有这些属性。

基于类的关键概念

因此,我们有如下关键概念:

1.创建一个对象之前,必须声明类,首先有必要界定其类
2.因此,该对象将由抽象成自身“象形和相似性”(结构和行为)的类里创建
3.方法是通过了严格的,直接的,一成不变的继承链来处理
4.子类包含了继承链中所有的属性(即使其中的某些属性是子类不需要的);
5.创建类实例,类不能(因为静态模型)来改变其实例的特征(属性或方法);
6.实例(因为严格的静态模型)除了有该实例所对应类里声明的行为和属性以外,是不能额外的行为或属性的。

让我们看看在JavaScript里如何替代OOP模型,也就是我们所建议的基于原型的OOP。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgfgws.html