06-继承
码路教育 6/22/2022
# 1. 继承
继承, 可以让多个构造函数之间建立关联, 便于管理和复用
# 1.1 不使用继承
// 分析需求:
// 人类, 属性: name, age 会说话
// 学生, 属性: name, age, className 会说话
// 工人, 属性: name, age, companyName 会说话
// 为什么要有继承:
// 继承: 将多个构造函数, 建立关联, 实现方便管理 和 方便复用
// 角度
// 1. 方法的继承
// 2. 实例化属性过程的复用
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log('会说话')
}
function Student (name, age, className) {
this.name = name
this.age = age
this.className = className
}
Student.prototype.sayHi = function() {
console.log('会说话')
}
function Worker (name, age, companyName) {
this.name = name
this.age = age
this.companyName
}
Worker.prototype.sayHi = function() {
console.log('会说话')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 1.2 继承之原型继承
原型继承: 通过改造原型链, 利用原型链的语法, 实现继承方法!
// 目标: 原型继承 => 继承方法
// 原型继承: 通过改造原型链实现继承, 利用原型链的特征实现继承,所谓的原型继承,就是在改造原型链
// 1. 定义Person构造函数
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.say = function () {
console.log('人类会说话')
}
// 2. 定义Student构造函数
function Student (name, age, className) {
this.name = name
this.age = age
this.className = className
}
// 3. 原型继承: 利用原型链, 继承于父级构造函数, 继承原型上的方法
// 语法: 子构造函数.prototype = new 父构造函数()
Student.prototype = new Person()
Student.prototype.constructor = Student;
Student.prototype.study = function() {
console.log('学生在学习')
}
let stu = new Student('张三', 18, '80期')
stu.say()
console.log(stu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
原型链继承的缺点:
- 如果父中的数据类型是引用数据类型,子对象修改了,另一个子对象也会受影响
- 创建Child对象是,不能传参
# 1.3 继承之组合继承
// 组合继承: 两种技术的组合, 原型链技术, 借用构造函数(call)结合, 发挥二者之长, 实现继承的方式
// 1. 原型链技术: 改造原型链, 实现继承方法
// Student.prototype = new Person()
// 2. 实例属性的构造过程没有得到复用, 可以用借用构造函数的方式, 实现复用
// Person.call(this, name, age)
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log('会说话')
}
function Student (name, age, className) {
// 不仅要执行Person构造函数, 且要让执行构造函数时的this指向创建出来的实例stu
// call
// 1. 调用函数
// 2. 改变函数执行时的this指向
Person.call(this, name, age)
this.className = className
}
Student.prototype = new Person()
const stu = new Student('zs', 7, '一年级一班')
stu.sayHi()
console.log(stu)
// 方法通过 原型继承
// 属性通过 父构造函数的.call(this, name, age)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 1.4 继承之寄生组合继承
function Person (name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log('会说话')
}
function Student (name, age, className) {
// 不仅要执行Person构造函数, 且要让执行构造函数时的this指向创建出来的实例stu
// call
// 1. 调用函数
// 2. 改变函数执行时的this指向
Person.call(this, name, age)
this.className = className
}
// 构造函数没有必要执行, 我们只需要的是原型链
Student.prototype = Object.create(Person.prototype)
const stu = new Student('zs', 7, '一年级一班')
stu.sayHi()
console.log(stu)
// 总结:
// Object.create() 以参数的对象, 作为新建对象的__proto__属性的值, 返回新建的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1.5 继承之ES6中的继承
// function Person (name, age) {
// this.name = name
// this.age = age
// }
// Person.prototype.sayHi = function() {}
// Person.prototype.jump = function() {}
// 人类
class Person {
// 类似于之前的构造函数
constructor (name, age) {
this.name = name
this.age = age
}
// 底层 => 这两个方法, 就是添加到 Person.prototype 上
sayHi () {
console.log('你好哇')
}
jump () {
console.log('会跳')
}
}
const p = new Person('zs', 18)
console.log(p)
// 继承关键字 => extends
// 老师类
class Teacher extends Person {
// 如果没有提供构造函数, 在继承时, 会默认自动借调父构造函数
constructor (name, age, lesson) {
// 你写的构造函数中, 没有借调父构造函数
super(name, age) // 触发调用父构造函数, 进行实例的属性初始化
this.lesson = lesson
}
teach () {
console.log('会教书')
}
}
const teacher = new Teacher('zs', 18, '教体育')
console.log(teacher)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41