原型与继承
原型与原型链
把当前对象作为实例来看待,那么他的__proto__是他的原型,而他的原型本身则是原型的原型的实例,而实例与原型的关系就构成了原型链
原型的概念
- 普通object类型下,原型存储在__proto__中,它有两个属性,constructor和__proto__
- 在函数类型中,有函数属性protoype,prototype有一个默认的constructor属性,用于记录实例是由哪个构造函数创建
- 原型对象的constructor指向构造函数本身
- 实例的__proto__与原型对象相等,即指向同一个内存地址
原型的优势
- 实例对属性的方法进行覆盖和重写不会影响原型
- 原型链的关系可以减少内存消耗
原型继承
原型链继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function VehicleInc(name) { this.name = name }
VehicleInc.prototype.getName = function() { return this.name }
function Benz() { this.model = [] }
Benz.prototype = new VehicleInc('Benz') Benz.prototype.addModel = function (model) { this.model.push(model) }
const benz = new Benz();
|
借用构造函数实现继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function VehicleInc(name) { this.name = name this.getName = function() { return this.name } }
function Benz() { VehicleInc.call(this, 'Benz') this.model = [] this.addModel = function () { this.model.push() } }
Benz.prototype = new VehicleInc()
const benz = new Benz();
|
组合式继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function VehicleInc(name) { this.name = name }
VehicleInc.prototype.getName = function() { return this.name }
function Benz() { VehicleInc.call(this, 'Benz') this.model = [] }
Benz.prototype = new VehicleInc() Benz.prototype.constructor = Benze Benz.prototype.addModel = function(model) { this.model.push(model) }
const benz = new Benz();
|
寄生组合式继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function VehicleInc(name) { this.name = name }
VehicleInc.prototype.getName = function() { return this.name }
function Benz() { VehicleInc.call(this, 'Benz') this.model = [] }
Benz.prototype = Object.create(VehicleInc.prototype) Benz.prototype.constructor = Benz Benz.prototype.addModel = function(model) { this.model.push(model) }
const benz = new Benz();
|
类继承
使用extends关键字
super
- 实现继承必须使用super,因为子类没有this, 如果不调用子类就得不到this对象
- super作为函数调用时是作为父类的构造函数
- super作为对象时,调用实例方法时为父类的原型对象,调用静态方法时为,super作为父类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class VehicleInc { constructor(name) { this.name = name }
getName() { return this.name } }
class Benz extends VehicleInc { constructor() { super('Benz') this.model = [] } addModel(model) { this.model.push(model) } getAllModel() { return `the ${super.getName()} has ${this.model.join('、')} models` } }
|