# 几种继承的方法
# 借助构造函数继承
parent.call(this)
子类实例可以继承父类上的属性,无法继承父类原型链上的属性
引用类型的值是独立的
function parent() {
this.name = 'Ben'
this.age = 12
this.arr = [1,2]
this.fn = () => {
console.log('parent fn')
}
}
// 父类原型链上定义方法 属性
parent.prototype.say = () => {
console.log('parent say!');
}
function child() {
// 通过 call() 方法改变 child 的this指向,使子类的函数体内执行父级的构造函数从而实现继承效果
parent.call(this)
this.sex = 1
}
const c1 = new child()
// 可以继承父类上属性
console.log(c1.name); // 'Ben'
c1.fn(); // parent fn
// 子类实例无法继承父类原型链上的属性
c1.say(); // Error
// 可以修改父类上的属性
c1.name = 'kkk'
console.log(c1.name) // kkk
c1.arr.push(3)
console.log(c1.arr); // [1,2,3]
// 引用类型的值是独立的
const c2 = new P1()
console.log(c2.name); // hello
console.log(c2.arr); // [1,2]
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
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
# 借助原型链实现继承
- 通过子类的实例修改父类上的属性和方法(引用类型的属性,基本数据类型的属性修改不会影响到其他子类) 其他子类实例的属性和方法也会被修改
function parent() {
this.name = 'Ben'
this.age = 12
this.nums = [1, 3];
this.fn = () => {
console.log('parent fn')
}
}
// 父类原型链上定义方法 属性
parent.prototype.say = () => {
console.log('parent say!');
}
function child() {
this.sex = 1
}
// 让子类的原型 直接等于父类实例
child.prototype = new parent();
const c1 = new child()
const c2 = new child()
console.log(c1.name); // 'Ben'
c1.fn() // parent fn
c1.say(); // parent say!
// 实例 c1 改变父类中的属性
// 实例 c2 也会改变
// nums 是引用数据类型 修改后会影响其他子类
// 但如果是 c1.nums = [1,2,3,4] 这样的赋值不会影响其他子类
c1.nums.push(4)
console.log(c1.nums); // [1,3,4]
console.log(c2.nums); // [1,3,4]
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
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
# 组合继承
- 多次调用父级调用函数
function parent() {
this.name = 'Ben'
this.age = 12
this.nums = [1, 3];
this.fn = () => {
console.log('parent fn')
}
}
// 父类原型链上定义方法 属性
parent.prototype.say = () => {
console.log('parent say!');
}
function child() {
parent.call(this)
this.sex = 1
}
// 让子类的原型 直接等于父类实例
child.prototype = new parent();
// child.prototype = parent.prototype;
const c1 = new child()
const c2 = new child()
console.log(c1.name); // 'Ben'
c1.fn() // parent fn
c1.say(); // parent say!
// 实例 c1 改变父类中的属性
// 实例 c2 也会改变
c1.nums.push(4)
console.log(c1.nums); // [1,3,4]
console.log(c2.nums); // [1,3]
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
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
# 组合继承(完美版)
function parent() {
this.name = 'Ben'
this.age = 12
this.nums = [1, 3];
this.fn = () => {
console.log('parent fn')
}
}
// 父类原型链上定义方法 属性
parent.prototype.say = () => {
console.log('parent say!');
}
function child() {
parent.call(this)
this.sex = 1
}
// 使用 Object.create()
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
const c1 = new child()
const c2 = new parent()
console.log(c1.constructor); // child
console.log(c2.constructor); // parent
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
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