【重学前端】004-JavaScript:我们真的需要模拟类吗
文章目录
- 【重学前端】004-JavaScript:我们真的需要模拟类吗
- 一、曾经的“模拟面向对象”
- 1、“模拟面向对象”
- 思维导图
- 早期情况概述
- 公司政治原因
- 2、ES6 提供了 class 关键字
- 二、什么是原型
- 0、思维导图
- 1、顺应人类自然思维的产物
- 2、基于“原型”描述对象
- 3、基于“类”描述对象
- 三、JavaScript 的原型
- 1、对原型系统的 2 条概括
- 2、访问和操作原型
- 3、三个方法
- 创建新对象
- 代码演示
- 运行结果
- 获得一个对象的原型
- 方法说明
- 代码演示
- 运行结果
- 设置一个对象的原型
- 方法说明
- 代码演示
- 运行结果
- 四、ES6 中的类
- 1、class 关键字
- 2、基本写法
- 代码示例
- 说明
- 3、类的继承
- 代码示例
- 说明
一、曾经的“模拟面向对象”
1、“模拟面向对象”
思维导图
早期情况概述
早期的 JavaScript 程序员一般有过使用 JavaScript **“模拟面向对象”**的经历;
实际上,JavaScript 本身就是正统的面向对象语言!
描述对象的方式 = 基于类(Java等) + 基于原型(JavaScript等);
基于类的描述方式更成功,导致人们错误地认为这样的方式才是面向对象。
公司政治原因
这模仿得不够彻底啊!如果 Java 的写法都能在这里使用,那对于 Java 程序员岂不是一件大好事!
如果 JavaScript 也是 sun 公司写的就好了,或者直接使用 Java 写前后端,岂不妙哉!
就像 TypeScript 的语法,和微软自家的 C# 就很像!
当然,JavaScript 本身也有很多实用而 Java 没有的特性!
由于公司的一些政治原因,JavaScript 在推出之时,被要求去模仿 Java ,因此有了 new
、this
等语言特性,使其看起来更像 Java !
2、ES6 提供了 class 关键字
ES6 提供了 class
这个关键字来定义类,尽管其仍然是基于原型运行时系统的模拟,但修正了一些常见的“坑”,统一了社区方案,这对语言的有很大好处!
二、什么是原型
0、思维导图
1、顺应人类自然思维的产物
原型是顺应人类自然思维的产物。
比如“照猫画虎”,这就是一种基于原型的思维!
再比如电影中的“外星人”,他们和人类很相似,这也是一种基于原型的思维!人们想象不出来外星人到底是什么样子,就在自身的基础上创造出“外星人”的样子!这就是基于原型的思维!
再比如电影、电视剧、小说中的故事,我们常说主人公的原型就是谁谁谁,我认为这也是基于原型的思维!
说了这么多,原型的含义也没啥复杂的了!多举例子是表达的妙诀!
2、基于“原型”描述对象
此时,我们就更倾向于描述一个东西像什么,比如老虎像大猫!
创建对象的方式:复制过来,改一改!
JavaScript 实现复制操作的两种方式:
引用方式: 新对象持有一个原对象的引用;
真复制: 直接复制原对象,新对象与原对象无任何关系!
3、基于“类”描述对象
比较基于“原型”,我们是把这一类对象抽象成一个模型,然后基于这个模型来描述具体的对象!比如学生这一类对象,我们把他们共有的状态和行为抽象成一个学生类,比如都有姓名、学号、年龄、性别等等,然后每一个具体的学生根据类这个模型创建出来,这就达到了描述对象的效果!
基于“类”比基于“原型”更抽象一点!
创建对象的方式:基于类模型,创建!
三、JavaScript 的原型
1、对原型系统的 2 条概括
抛开模拟 Java 类的复杂语法设施,原型系统非常简单!
- 如果所有对象都有私有字段[[prototype]],就是对象的原型;
- 读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找不到为止。
2、访问和操作原型
这个原型在 ES6 以来提供了一系列内置函数,以便更为直观地访问和操作原型。
3、三个方法
-
Object.create
:根据指定的原型创建新对象,原型可以是 null ; -
Object.getPrototypeOf
:获得一个对象的原型; -
Object.setPrototyoeOf
:设置一个对象的原型。
创建新对象
代码演示
运行结果
如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找不到为止!
获得一个对象的原型
方法说明
代码演示
运行结果
设置一个对象的原型
方法说明
代码演示
运行结果
四、ES6 中的类
1、class 关键字
ES6 加入了新特征 class ,在任何场景下都推荐使用 ES6 语法来定义类,令 function 回归原本的函数语义。
ES6 中引入了 class 关键字,并且在标准中删除了所有 [[class]] 相关的私有属性描述,类的概念正式从属性升级成语言的基础设施,从此,基于类的编程方式成为了 JavaScript 的官方编程范式。
2、基本写法
代码示例
在现有的类语法中,getter/setter 和 method 是兼容性最好的。
说明
类的写法实际上也是由原型运行时来承载的,逻辑上 JavaScript 认为每个类是有共同原型的一组对象,类中定义的属性和方法被写在原型对象上。
3、类的继承
代码示例
说明
使用 extends 关键字自动设置了 constructor,并且会自动调用父类的构造函数,这是一种更少坑的设计。
一些激进的观点认为,class 关键字和箭头运算符可以完全替代旧的 function 关键字,它更明确地区分了定义函数和定义类两种意图,这是有一定道理的。