尝试采用追溯法学习面向对象。
OOP to me means only messaging, local retention and protection and hidding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I'm not aware of them.
—— Alan Kay
Decide which classes you want; provide a full set of operations for each class; meke commonality explicit by using inheritance.
—— Bjarne Stroustrup
对我来说,面向对象就是一片汪洋大海,航行其中,总是有一片接一片的迷雾...
前面的碎碎念
如何学习面向对象方面的知识?(for me)
- 回顾重学前端专栏中JS对象部分的内容。
- 找出家里所有JS的书籍,翻阅对象相关章节。
- 晚上查找相关的文章博客。
把面向对象这个概念用追溯法写一篇文章,对目前的我还是存在一定的难道。只能从wiki开始,了解面向对象的历史。
面向对象的语言
语言名称 | 发行时间 | 主要设计者 | 重要概念 |
---|---|---|---|
Simula | 1962年 | Ole-Johan Dahl | 第一个面向对象的编程语言,介入对象、类、子类、继承等概念 |
Smalltalk | 1972年 | Alan Kay | 一种面向对象的动态类型的编程语言,推动了之后众多语言的产生 |
C++ | 1983年 | Bjarne Stroustrup | 一种通用程序设计语言,支持面向对象程序设计、泛型程序设计 |
Common Lisp | 1984年 | Lisp编程语言的方言,支持多分派和方法组合的对象系统 | |
Objective-C | 1984年 | Brad Cox | 扩展了标准的ANSI C编程语言,加入Smalltalk式的消息传递机制 |
Perl | 1987年 | Larry Wall | 一个通用的脚本语言,借鉴了C、sed、awk、shell脚本、Lisp等 |
Python | 1991年 | Guido van Rossum | 一种广泛使用的解释型、高级编程、通用型编程语言 |
Ruby | 1995年 | 松本行弘 | 一种面向对象、命令式、函数式、动态的通用编程语言 |
Java | 1995年 | James Gosling | 拥有跨平台、面向对象、泛型编程的特性 |
JavaScript | 1995年 | Brendan Eich | 解释性编程语言,面向对象编程,命令式编程,以及函数式编程。 |
1960年,Ole-Johan Dahl等在挪威电子计算中心,开发出simula语言,被认为是第一个面向对象的编程语言。在Simula 67 中介入了对象、类、子类、继承、虚过程、协程、离散时间模拟、垃圾收集。
在Google Scholar上查阅Ole-Johan Dahl相关的论文,对Simula的定义是 an ALGOL-based simulation language,a language for programming and description of discrete event systems, introduction and user's manual.
JavaScript面向对象
编程语言中,描述对象的方式,C++、Java是 “类”,JavaScript 是用 “原型”。JavaScript 并非第一个使用原型的语言,之前的self、kevo 等语言就是使用原型来描述对象。
原型系统的“复制操作”:Self语言 复制对象,从此两个对象再无关联。JavaScript是新对象持有一个原型的引用。
Self语言,是在Smalltalk的基础上发展而来,是一种基于原型的面向对象的程序设计语言。1986年由施乐PARC的David Ungar和Randy Smith设计。取消了类的概念,只有对象的概念。
JS对象的特征
- 具有唯一标识 —— 内存地址。
- 多个不同的状态 —— 属性。
- 可能改变状态的行为 —— 方法(JS中也是属性)。
JS 允许运行时改变状态和行为,提供数据属性(value / writable / enumerable / configurable)和访问器属性(getter/setter/enumerable / configurable)。
把属性和方法,通过字面量、函数、构造函数、原型等模式封装成一个对象。对象之间通过原型链、构造函数、组合继承等方式实现继承。在继承链的不同层次中一个方法名可被多次定义,实现相对多态。
原型
对象都有私有字段[[prototype]],就是对象的原型。读一个属性,如果对象本身没有,则会继续访问对象的原型,直到原型为空或者找到为止。
原型的访问操作方法:
- Object.create 根据指定的原型创建新对象,原型可以是 null(ES5)
- Object.getPrototypeOf 获得一个对象的原型(ES5)
- Object.setPrototypeOf 设置一个对象的原型(ES6)
- super 引用简化原型的访问 (ES6)
类
- ES3及之前,类的定义是一个私有属性[[class]],语言标准为内置类型诸如 Number、String、Date 等指定了[[class]]属性,以表示它们的类。访问[[class]]属性的方式是 Object.prototype.toString。new 运算是唯一一个可以指定[[prototype]]的方法。
- ES5 开始,[[class]] 私有属性被 Symbol.toStringTag 代替。
- ES6 中加入了新特性 class,在标准中删除了所有[[class]]相关的私有属性描述,使用 extends 关键字自动设置了 constructor。typeof 定义的类,返回function,因此类声明仅是自定义类型声明(User.prototype)的语法糖。
ES6新增了class,但并不意味着JS中真的有类。JS的类与其他语言的类并不一样。
—— 你不知道的JS