目录
方式一:原型链继承
// 原型链继承
let parentObj = {
type: 'parentObj'
}
let a = new Object(parentObj)
// 修改原型链上的方法
a.__proto__.toString = "a改了toString方法"
无法传参;
无法多继承;
可以单继承,但属性共享。
方式二:构造函数继承
function Parent() {
this.toString = function () {
console.log(`Parent 的 toString`)
}
console.log('Parent')
}
Parent.prototype.parentSayHello = function () {
console.log('Hello, I am parent')
}
function Child() {
Parent.apply(this, Array.prototype.slice.call(arguments))
}
Child.prototype.childSayHello = function () {
console.log('Hello, I am child')
}
const parent = new Parent()
const child = new Child('child')
每次创建实例,都需要调用父类的构造函数,会造成性能上的浪费;
子类使用apply后继承了父类中构造函数中属性和方法,但是原型链上的方法没有被继承。
方式三:组合式继承
// 组合继承
function Parent() {
this.toString = function () {
console.log(`Parent 的 toString`)
}
console.log('Parent')
}
Parent.prototype.parentSayHello = function () {
console.log('Hello, I am parent')
}
function Child(tag) {
Parent.apply(this, Array.prototype.slice.call(arguments))
this.tag = tag
}
// 子类刚通过构造函数继承后,再去继承父类的原型链上的属性或方法
Child.prototype = new Parent()
Child.prototype.constructor = Child
Child.prototype.childSayHello = function () {
console.log('Hello, I am child')
}
const child = new Child('child')
每次创建实例,都需要调用父类的构造函数,会造成性能上的浪费;
方式四:原型式继承
// 原型继承
let parentPO = {
type: 'parentPO',
toString: function () {
console.log(`parentPO 的 toString`)
}
}
let childPO = Object.create(parentPO)
childPO.toString = function() {
console.log(`childPO 的 toString`)
}
childPO.__proto__.toString = function() {
console.log(`childPO 的 toString`)
}
通过使用 Object.create() 方法实际是对父类的属性和方法浅拷贝,故属性共享。
方式五:寄生式继承
// 寄生继承
let parentPA = {
type: 'parentPA',
toString: function () {
console.log(`parentPA 的 toString`)
}
}
function ChildPA(){
let clone = Object.create(parentPA)
clone.selfToString = function () {
console.log(`childPO 的 selfToString`)
}
return clone
}
const child = new ChildPA()
使用 Object.create() 方法对父类浅拷贝后,再添加私有方法。
方式六:寄生组合继承
// 寄生组合式继承
function inherits(Parent, Child){
Child.prototype = Object.create(Parent)
Child.prototype.constructor = Child
}
function Parent(){
this.toString = function () {
console.log(`parent 的 toString`)
}
console.log('parent')
}
Parent.prototype.parentSayHello = function () {
console.log('Hello, I am parent')
}
function Child(){
Parent.apply(this, Array.prototype.slice.call(arguments))
}
inherits(Parent, Child)
Child.prototype.childSayHello = function () {
console.log('Hello, I am child')
}
const child = new Child()
将父类的属性或方法apply到当前子类,实现属性私有;
可以传参;
解决了构造函数多次调用的问题。
综合来说,寄生组合式继承是目前最优的继承方式。
ES6中的 extends实现
// ES6中的 extends 继承
class Person {
constructor(hobby) {
this.hobby = hobby
}
// Person.prototype.getHobby = function(){}
getHobby = function () {
console.log(this.hobby)
}
}
class Student extends Person {
constructor(hobby, age) {
super(hobby)
this.age = age
}
}
const xiaoming = new Student('play game', 10)
xiaoming.getHobby()