原型与继承

函数对象

由function创造出来的函数
系统内置函数对象 Function,Object,Number,String
只有函数对象才有 prototype 属性

原型对象 prototype

指针 proto

所有对象都有proto属性,指向构造该对象的构造函数的prototype
function Person() {
this.name = ‘name’
}
var person1 = new Person()
person1._proto = Person.prototype

构造函数 constructor

function Person() {
this.name = ‘name’
}
var person1 = new Person()
person1.constructor = Person
person1._proto.constructor = Person.prototype.constructor = Person

简单原型链继承

1
2
3
4
5
6
7
8
function Super() {
this.name = 'super'
}
function Sub() {
}
// 利用原型链实现继承, 缺点:包含引用类型值的原型属性会被所有实例共享
Sub.prototype = new Super()

构造函数继承

1
2
3
4
5
6
7
function Super() {
this.name = 'super'
}
// 缺点:方法都只能在构造函数中定义,没有办法实现方法的复用
function Sub() {
Super.call(this, ...arguments)
}

组合式继承

使用原型链实现对原型方法的继承,使用构造函数实现对实例属性的继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Super() {
this.name = 'super'
}
Super.prototype.sayName = function() {
return this.name
}
function Sub() {
// 通过 构造函数继承属性
Super.call(this, ...arguments)
}
// 利用原型链实现继承, 缺点:包含引用类型值的原型属性会被所有实例共享
Sub.prototype = new Super()
// 重写了 Sub 的 prototype 属性,因此其 constructor 也被重写了,需要手动修正
Sub.prototype.constructor = Sub
// 定义子类自己的方法
Sub.prototype.sayAge = function() {
return this.age
}

原型式继承

寄生式继承

1
2
3
4
5
6
7
function createAnother(original) {
var clone = Object.create(original)
clone.sayHi = function() {
console.log("Hi")
}
return clone
}

组合寄生式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Super() {
this.name = 'super'
}
Super.prototype.sayName = function() {
return this.name
}
function Sub() {
Super.call(this, ...arguments)
}
Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.prototype.sayAge = function() {
return this.age
}