深入理解javascript混合对象“类”(一)

简介: 深入理解javascript混合对象“类”(一)

前言

      javascript是一门面向对象语言,但是与传统面向对象语言不同,javascript原理上并没有类的说法,学习过传统面向对象语言的同学们可能知道,面向类的设计模式有三种:实例化(instantiation)、继承(inheritance)和(相对)多态(polymorphism)。但是这些设计模式无法对应到javascript的对象机制,所以在深入javascript的原理之前,这一章我们将先学习有关面向类的设计模式的相关知识


正文

       类 / 继承描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法。面向对象编程强调的是数据和操作数据的行为本质上是互相关联的(当然,不同的数据有不同的行为),因此好的设计就是把数据以及和它相关的行为打包(或者说封装)起来。这在正式的计算机科学中有时被称为数据结构。


我们可以在软件中定义一个 Vehicle 类和一个 Car 类来对这种关系进行建模。Vehicle 的定义可能包含推进器(比如引擎)、载人能力等等,这些都是 Vehicle 的行为。我们在 Vehicle 中定义的是(几乎)所有类型的交通工具(飞机、火车和汽车)都包含的东西。在我们的软件中,对不同的交通工具重复定义“载人能力”是没有意义的。相反,我们只在 Vehicle 中定义一次,定义 Car 时,只要声明它继承(或者扩展)了 Vehicle 的这个基础定义就行。Car 的定义就是对通用 Vehicle 定义的特殊化。虽然 Vehicle 和 Car 会定义相同的方法,但是实例中的数据可能是不同的,比如每辆车独一无二的 VIN(Vehicle Identification Number,车辆识别号码),等等。这就是类、继承和实例化。----《你不知道的javascript》


       类的另一个核心概念是多态,这个概念是说父类的通用行为可以被子类用更特殊的行为重写。实际上,相对多态性允许我们从重写行为中引用基础行为。


“类”设计模式

       你可能从来没把类作为设计模式来看待,讨论得最多的是面向对象设计模式,比如迭代器模式、观察者模式、工厂模式、单例模式,等等。从这个角度来说,我们似乎是在(低级)面向对象类的基础上实现了所有(高级)设计模式,似乎面向对象是优秀代码的基础。

       其实除了面向类编程还有过程化编程,这种代码只包含过程(函数)调用,没有高层的抽象。所以其实类并不是必须的编程基础,而是一种可选的代码抽象。


javascript中的类

       在相当长的一段时间里,JavaScript 只有一些近似类的语法元素(比如 new 和 instanceof),不过在后来的 ES6 中新增了一些元素,比如 class 关键字。但是javascript实际上并没有类,看过之前我写的设计模式系列的同学们可能知道,javascript是一门基于原型继承的语言,类(class)只是一种语法糖,给习惯面向类的软件设计的开发者们多一种选择


类的机制

       因为这一小结并没有在javascript中有所体现,写的原因只是为了帮助大家熟悉传统面向类的设计模式,所以下面的相关例子会采用伪代码形式展示


构造函数

       类实例是由一个特殊的类方法构造的,这个方法名通常和类名相同,被称为构造函数。这个方法的任务就是初始化实例需要的所有信息(状态)。


640.png

       我们可以调用类构造函数来生成一个 CoolGuy 实例:



       类构造函数属于类,而且通常和类同名。此外,构造函数大多需要用 new 来调,这样语言引擎才知道你想要构造一个新的类实例。


类的继承

       在面向类的语言中,你可以先定义一个类,然后定义一个继承前者的类。后者通常被称为“子类”,前者通常被称为“父类”。这里我们举一个例子来进一步说明,假设有一个Vehicle类,这是引擎类,提供一个推进能力,比如飞机火车上都有,然后我们定义一个Car类,很明显对于不同的交通工具再额外定义推进能力是没必要的,这时候就需要让Car类继承Vehicle类。可以给出如下伪代码:




多态

       Car 重写了继承自父类的 drive() 方法,但是之后 Car 调用了 inherited:drive() 方法,这表明 Car 可以引用继承来的原始 drive() 方法。快艇的 pilot() 方法同样引用了原始drive() 方法。这个技术被称为多态或者虚拟多态。多态的另一个方面是,在继承链的不同层次中一个方法名可以被多次定义,当调用方法时会自动选择合适的定义。


多重继承

       从表面上来,对于类来说这似乎是一个非常有用的功能,可以把许多功能组合在一起。然而,这个机制同时也会带来很多复杂的问题。如果两个父类中都定义了 drive() 方法的话,子类引用的是哪个呢?难道每次都需要手动指定具体父类的 drive() 方法吗?

       JavaScript 要简单得多:它本身并不提供“多重继承”功能。许多人认为这是件好事,因为使用多重继承的代价太高。


小结

       这一章我们介绍了有关传统面向类的设计模式,了解到了类的构造函数,多态和继承,下一章我们将继续介绍javascript在其中的解决方式


目录
相关文章
|
10天前
|
Web App开发 JavaScript 前端开发
JavaScript 类(class)
JavaScript 类(class)
15 2
JavaScript 类(class)
|
2天前
|
JSON JavaScript 前端开发
js如何格式化一个JSON对象?
js如何格式化一个JSON对象?
10 3
|
9天前
|
JavaScript 前端开发
js之浏览器对象|28
js之浏览器对象|28
|
8天前
|
JavaScript 前端开发 Java
JavaScript 类知识点概览
概览JavaScript中类的知识点,包括类的定义和实现、添加方法和get/set方法、类的继承和静态方法的使用。通过学生类和人员类的例子,演示了类的构造器、方法定义、继承关系和静态方法的调用。
JavaScript 类知识点概览
|
9天前
|
JavaScript 前端开发 开发者
JavaScript 类继承
JavaScript 类继承
12 1
|
11天前
|
JavaScript 安全
ES6中JS类实现的解读
ES6中JS类实现的解读
15 2
|
1月前
|
JavaScript 前端开发
JavaScript基础知识-构造函数(也称为"类")定义
本文介绍了JavaScript中构造函数(也称为“类”)的定义和使用方法。
26 1
JavaScript基础知识-构造函数(也称为"类")定义
|
16天前
|
JavaScript 前端开发 索引
|
23天前
|
JavaScript 前端开发
JavaScript Boolean(布尔) 对象
Boolean(布尔)对象用于将非布尔值转换为布尔值(true 或者 false)。
29 8
|
24天前
|
JavaScript 前端开发
JS中Promise的类式实现写法
JS中Promise的类式实现写法