继承的要点
- proptotyp和[[prototype]]。这两个分别为显式原型和隐式原型。
- 显示是用来实现基于原型链的继承和属性共享 (implement prototype-based inheritance and shared properties),指向原型对象。隐式是也是用来构成原型链的(_proto_是不规范的浏览器实现,可直接使用),指向创建这个对象的原型对象。
- 构造函数都有一个原型对象,原型对象存在一个constrcutor属性指向构造函数。构造函数的实例的[[prototype]]属性不可访问,可用Object.getPrototypeOf()标准方法访问该属性,返回为原型对象。
- 原型链实现的本质是重写子类的原型对象。原型对象的赋值一旦采用了字面量形式,那么原型就被重写,constrcutor属性指向Object,原型的[[prototype]]指向超类原型。实例与原型对象的[[proptotype]]就完成了链的连接。
继承方法的个人记忆
- 着重记忆组合式继承+寄生组合式继承,这两种都是由另外两种继承组合而成,要组合当然是因为它们各自有各自的缺陷。而两者相似的地方都是用子类构造函数来继承属性(此处是调用超类构造(call/apply),得到一个副本),用子类原型来继承方法。(前者new,后者create)
- 记住Object.create(),它是原型式继承的规范化。是寄生组合式继承的重要部分。
共用超类代码
function Super() {
this.value = ['a', 'b', 'c']
}
Super.prototype.getValue = function () {
return this.value.
}
复制代码
一: 原型链继承
//代码实现
function Sub() {}
Sub.prototype = new Super()
var instance = new Sub() //使用
复制代码
缺点:
- 原型中有引用类型,实例可以修改,不安全.
instance.value[3] = 'd'
var instance2 = new Sub()
instance2.value //['a','b','c','d'] 共享的本质
复制代码
- 不能给超类的构造函数传递参数
二:借用构造函数
function Sub() {
//继承属性
Super.call(this,arguments) //将Super当作普通函数调用
}
复制代码
缺点:
- 虽然解决了向超类传参的问题,但是由于没有new,使得超类原型里的方法对子类来说不可见
三:组合继承式 = 一 + 二
function Sub(){
Super.call(this,arguments)
}
Sub.prototype = new Super()
Sub.prototype.constructor = Sub //原型被重写,保持指向
Sub.prototype.fun = () => ()
复制代码
解析:
- 该方法解决了一二的缺陷,使用instanceof和**isPrototype()**能识别基于三创建的对象。是最常用的方法。
- 唯一不足是调用了两次Super()
四:原型式继承
var Person = {}
function object(o) {
function F() {}
F.prototype = o
return new F()
}
复制代码
解析:
- 该方法一样存在共享引用类型值的问题
- 应用场景为只想让一个对象与另一个对象保持类似的情况。为此ES5有Object.create()规范了原型式继承:接受两个参数,第一个为作为新对象原型的对象,第二个为新修对象的额外属性。
五:寄生式继承(不重要)
function obj(o) {
let clone = Object.create(o)
clone.fun = () => ()
return clone
}
复制代码
解析: 无法函数复用。
六:寄生组合式继承
function inheritPrototype (Sub, Super) {
let obj = Object.create(Super.prototype)
obj.constructor = Sub
Sub.prototype = obj
}
function Sub() {
Super.call(this,arguments) //属性继承
}
inheritPrototype(Sub,Super)
Sub.prototype.fun = () => () //添加自己的原型方法
复制代码
解析: 解决了组合式继承的使用了两次构造函数的问题。很理想的方法。
todo : 配图
写的难看勿喷,这算是个人的读书笔记吧。
如有错误请指正,谢谢。
复制代码