学任何东西, 都应该了解历史, 至少要知道是什么, 为何被创造, 为了解决什么, 存在什么问题.
其实在 90 年代末, 网景公司仅仅是想要一款可以嵌入到浏览器内执行的一门脚本语言, 用于处理基本的用户交互, 比如处理表单, 数据校验等简单操作, 而当时找来了 Brendan Eich 创造这么一种语言.
Brendan Eich 是谁呢? 这个你要自己谷歌了. 但是这里说一下, 在网景赶着把脚本语言嵌入浏览器好去争夺市场的前提下, Brendan Eich 仅仅用十天就把 JavaScript ( 当时还没这个名字 ) 创造出来. 其中:
- 基本语法沿用 C 风格
- 正则表达式抄了 perl
- 函数设计抄了 scheme
- 数据类型设计抄了 java
- 继承模型抄了 self
还有很多东西就不一一列举了, 但是到这里, 我想读者应该很明白 JavaScript 仅仅是当年为了抢份额而急忙创造的语言, 而且还是个大杂烩, 所以诸如字符集这种历史问题也挺多的, 但是谁又能想到后来呢.
到这里也顺便说一下 JavaScript 的面向对象设计, 大部分写 JavaScript 的后台都认为 JS 并不存在面向对象的概念, 但是我想说的是, 其实是存在的, 并且是 95 年面世那一刻开始就存在, 而不是所谓的到了 es6 才引入( class 关键字仅仅是颗糖罢了 ). 面向对象并不是只有基于类对象的实现, 同时也有基于原型链的实现, 只不过基本上所有主流的服务端语言的面向对象都是基于类对象来实现, 而且越来越火, 大家( 包括我 )有种先入为主的印象而已.
简而言之呢, 基于类对象( class-based )实现的意思就是, 以类对象为原型创建实例, 而你想继承这个实例拥有的一切属性, 只能通过创建新的类对象, 然后继承对应的类对象并创建实例, 才能达到继承的目的.
而基于原型对象( prototype-based )实现的意思就是, 取消类对象的概念, 每一个对象都是一个原型, 如果借用 class-based 的概念来解释的话, 那就是无论是类对象, 还是实例对象, 都可以被继承并创建新的实例, 模糊了类与实例的界限.
其实这就是最经典的 smalltalk( class-based ) 和 self( prototype-based ) 两门语言的不同特点, 这里有一份文档描述了关于两者对面向对象的实现的不同点. Self: The Power of Simplicity
参考:
JavaScript语言的历史
Smalltalk wiki
Self wiki