原型链的继承原理
让子类的原型对象指向父类的实例,当子类实例找不到对应的属性和方法时,会沿着原型链往上找。
1 | function Parent() {
|
2 | this.name = ['张三']
|
3 | }
|
4 |
|
5 | Parent.prototype.getName = function () {
|
6 | return this.name
|
7 | }
|
8 |
|
9 | function Child() {
|
10 |
|
11 | }
|
12 |
|
13 | Child.prototype = new Parent()
|
14 |
|
15 | Child.prototype.constructor = Child
|
16 |
|
17 | const child = new Child()
|
18 | console.log(child.name);
|
19 | console.log(child.getName());
|
20 |
|
21 | const child2 = new Child()
|
22 | child2.name[0] = '李四'
|
23 |
|
24 | console.log(child.name);
|
25 | console.log(child2.name);
|
原型链继承的弊端:
- 原型指向同一个原型实例,当有多个原型指向同一个原型实例时,修改任意一个影响其它的。
- 没有实现 super 功能。对父类进行传参
构造函数继承
在子类的构造函数中,执行父类的构造函数,并为其绑定子类的this。
1 | function Parent(name){
|
2 | this.name = [name]
|
3 | }
|
4 |
|
5 | Parent.prototype.getName = function(){
|
6 | return this.name
|
7 | }
|
8 |
|
9 | Parent.prototype.age = 10;
|
10 |
|
11 | function Child (){
|
12 | Parent.call(this,'李四')
|
13 | }
|
14 |
|
15 | const child = new Child()
|
16 | const child2 = new Child()
|
17 | child2.name[0] = '张三'
|
18 |
|
19 | console.log(child.name);
|
20 | console.log(child2.name);
|
21 | console.log(child2.getName());
|
22 | console.log(child.age);
|
构造函数继承弊端:
组合式继承
用原型链实现对原型属性和方法的继承,用借用构造函数继承来实现对实例属性的继承。
1 | function Parent(name){
|
2 | this.name = [name]
|
3 | }
|
4 |
|
5 | Parent.prototype.getName = function(){
|
6 | return this.name
|
7 | }
|
8 |
|
9 | Parent.prototype.age = 10;
|
10 |
|
11 | function Child (){
|
12 | Parent.call(this,'李四')
|
13 | }
|
14 |
|
15 | Child.prototype = new Parent()
|
16 | Child.prototype.constructor = Child
|
17 |
|
18 | const child = new Child()
|
19 | const child2 = new Child()
|
20 | child2.name[0] = '张三'
|
21 |
|
22 | console.log(child.name);
|
23 | console.log(child2.name);
|
24 | console.log(child2.getName());
|
25 | console.log(child.age);
|
组合式继承弊端:
- 创建的实例和原型上存在两份相同的属性
- 调用两次父构造函数,一次是在创建子类型原型时(new Child()),另一次是在子类型构造函数内部(Parent.call)。
寄生式组合继承
1 | function Parent(name){
|
2 | this.name = [name]
|
3 | }
|
4 |
|
5 | Parent.prototype.getName = function(){
|
6 | return this.name
|
7 | }
|
8 |
|
9 | Parent.prototype.age = 10;
|
10 |
|
11 | function Child (){
|
12 | Parent.call(this,'李四')
|
13 | }
|
14 |
|
15 |
|
16 | Child.prototype = Object.create(Parent.prototype)
|
17 | Child.prototype.constructor = Child
|
18 |
|
19 | Child.prototype.getAge = function(){
|
20 | console.log(this.age);
|
21 | }
|
22 |
|
23 | const child = new Child()
|
24 | const child2 = new Child()
|
25 | const parent = new Parent()
|
26 |
|
27 | child2.name[0] = '张三'
|
28 | console.log(child.name);
|
29 | console.log(child2.name);
|
30 | console.log(child2.getName());
|
31 | console.log(child.age);
|
32 | console.log(parent);
|