JavaScript中对象的继承模式

it2025-11-25  5

目录

前言1、原型链父子继承2、利用call函数继承3、原型链父子+call函数-组合继承


前言

阅读此文前需先掌握原型对象、原型链及call函数的使用方法

JavaScript原型对象及原型链相关总结

JavaScript中call、apply、bind的应用及函数中的this指向相关总结

没问题的话就请往下看吧

1、原型链父子继承

我们都知道,实例对象可以使用其原型对象的一些方法 但是如果有以下这么一种情况: 我们自行创建了两个构造函数A和B,B的实例想要使用A的方法,这是否可行呢,看代码

有两个构造函数A和B B的实例b1想要使用A的方法 需要将B的显式原型设置为A的实例 同时要将B的显式原型上的constructor 设置为B自身

- 代码例:

// 原型链父子继承 // 创建构造函数Father,我们称为父类型 function Father(name, age){ this.name = name this.age = age } // 给Father函数的原型上添加方法setName Father.prototype.setName = function(name) { this.name = name } // 创建构造函数Child1 function Child1(name, age){ this.name = name this.age = age } // 创建构造函数Child1的实例c1 let c1 = new Child1('sky', 12) // c1能否使用setName方法? // 当然是不可以的,因为setName是Father的方法 // c1的原型链中并不存在此方法 c1.setName() // 报错 // 不过是有办法可以实现的 // 创建构造函数Child2,这边称为子类型 function Child2(name, age){ this.name = name this.age = age } // 只有实例对象才能看得到其构造函数的方法 // 构造函数的显式原型默认指向一个空对象 // 我们把这个对象,改为那个构造函数的实例对象 // 这一步非常重要 ↓ 让子类型的显式原型成为父类型的实例对象 Child2.prototype = new Father() console.log(Child2) // 创建构造函数Child2的实例c2 let c2 = new Child2('sky', 12) console.log(c2.name) // 'sky' // c2使用setName方法(子类型的实例就可以使用父类型的方法了) c2.setName('jack') console.log(c2.name) // 'jack' // 最后其实还有个小问题,每个实例对象都有一个属性 constructor // constructor 属性应该指向其实例对象的构造函数 // 但由于上面的代码,导致c2的constructor变成了Father console.log(c2.constructor) // 这边会输出Father的函数体 // 但这是我们不希望看到的,因为c2是Child2的实例,这边可以做如下修正 // 让子类型的显式原型上的constructor指向子类型 Child2.prototype.constructor = Child2 console.log(c2.constructor) // 这次就输出了Child2的函数体

2、利用call函数继承

有两个构造函数A和B 利用call函数,可以在函数B内部使用函数A 这样一来,即便函数B自身没定义的属性规则,也能使用函数A的规则去实行 注意:这个方法并不会改变原型链关系,只能称之为“伪继承”

- 代码例:

// 利用call函数继承 // 创建构造函数Father,父类型 function Father(name, age) { this.name = name this.age = age } // 创建构造函数Child,子类型 function Child(name, age, height) { // 利用call函数调用Father // 相当于this.Father(name, age),这边的this是Child的实例对象 Father.call(this, name, age) this.height = height } // 创建实例对象c let c = new Child('sky', 18, 180) console.log(c.name, c.age, c.height) // 'sky' 18 180 // 利用call函数,就可以在构造函数内部,使用其他构造函数 // 但要注意的是,这个方法并不会改变原型链的关系,只能称之为“伪继承”

3、原型链父子+call函数-组合继承

上面2个都看懂的话,下面这个就是组合在一起使用,应该都能看明白了

- 代码例:

// 原型链父子+call函数-组合继承 // 创建构造函数Father,父类型 function Father(name, age){ this.name = name this.age = age } // 给Father函数的原型上添加方法setName Father.prototype.setName = function(name) { this.name = name } // 创建构造函数Child,子类型 function Child(name, age, height){ // 利用call函数调用Father的方法 Father.call(this, name, age) this.height = height } // 让Child的原型成为Father的实例 Child.prototype = new Father() // 修正constructor指向 Child.prototype.constructor = Child // 给Child函数的原型上添加方法setAge Child.prototype.setAge = function(age) { this.age = age } // 创建Child实例c let c = new Child('sky', 18, 180) c.setName('jack') c.setAge(24) console.log(c.name, c.age, c.height) // 'jack' 24 180

- Recorded by Scorpio_sky@2020-10-24

最新回复(0)