name | title | tags | categories | info | time | desc | keywords | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
《JavaScript设计模式与开发实践》学习笔记(二) |
《JavaScript设计模式与开发实践》学习笔记(二) |
|
学习笔记 |
第一部分、第 1 章 面向对象的 JavaScript(下) |
2019/9/12 |
JavaScript设计模式与开发实践, 资料下载, 学习笔记 |
|
JavaScript 一开始并没有类的概念。
在以类为中心的面向对象编程语言中,类和对象的关系可以想象成铸模和铸件的关系,对象 总是从类中创建而来。而在原型编程的思想中,类并不是必需的,对象未必需要从类中创建而来, 一个对象是通过克隆另外一个对象所得到的。就像电影《第六日》一样,通过克隆可以创造另外 一个一模一样的人,而且本体和克隆体看不出任何区别
本节我们将首先学习第一个设计模式——原型模式。
原型模式的实现关键,是语言本身是否提供了clone
方法。ECMAScript 5 提供了Object.create
方法,可以用来克隆对象。在不支持Object.create
的浏览器中,可以使用下面的代码达到相同的效果:
Object.create = Object.create || function (obj) {
var F = function () {}
F.prototype = obj
return new F()
}
笔者注:这里的“克隆”并不是传统意义上的克隆,得到的对象并非与被克隆的对象完全一样,只是外在表现十分相似,事实上,这是基于原型链的一种继承。
在用 Java 等静态类型语言编写程序的时候,类型之间的解耦非常重要。使用 new XXX 创建对象的方式显得十分僵硬,大多数时候,我们都需要使用工厂模式和抽象工厂模式来帮助我们解决这个问题。但这两个模式会增加很多额外的代码。
而 JavaScript 相较于基于对象的语言,它的对象系统是基于原型模式搭建的。
JavaScript 基于原型的面向对象系统参考了 Self 语言和 Smalltalk 语言。
原型编程范型至少包含以下基本规则:
- 所有的数据都是对象
- 要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并“克隆”它
- 对象会记住它的原型
- 如果对象无法响应某个请求,它会把这个请求委托给自己的原型
JavaScript 在设计的时候,模仿 Java 引入了两套类型机制:基本类型和对象类型。从现在的眼光以及原型编程范型的要求来看,这并非是一个好的设计。
所以我们不能说在 JavaScript 中所有的数据都是对象,只能说所有的对象都有一个根对象存在,所有的 JavaScript 对象都是从某个对象上“克隆”而来的。
这个根对象就是Object.prototype
,所有的对象与原型对象之间都使用一根名为__proto__
的纽带相连,而Object.prototype.__proto__
指向null
,代表这个继承链接就此打住。
除了根对象Object.prototype
本身以外,任何对象都有一个原型。通过Object.create(null)
可以创建出没有原型的对象。
另外,ECMAScript 6 带来了 Class 语言,但这并不意味着 JavaScript 从此成为了一门基于类的语言,事实上,Class 只是原型机制的语法糖而已,其背后依然是通过原型链来创造对象,完成继承。