js实现继承的几种方式

101 阅读1分钟

实现继承,就必须要提供个父类(继承谁,提供继承的属性)

function Person(name) {
    this.name = name 
    this.sum = function(){
        alert(this.name)
    }
}
Person.prototype.age = 10
1. 原型链继承
function parent(){
    this.name = 'joe'
}
parent.prototype = new Person()
var son = new parent()

image.png

image.png

特点:实例继承了构造函数的所有属性,父类构造函数属性,父类原型的属性
缺点:会继承父类所有属性,无法给父类属性传参,继承单一
2. 构造函数式继承
function Con() {
    Person.call(this, 'honghong')
    this.age = 12
}
var con1 = new Con()

image.png

image.png

特点:

1.只继承了父类构造函数的属性

2.子实例可以向父类实例传参

3.解决了原型链继承的缺点

4.可实现多继承,通过call多个构造函数实现

缺点:

1.只继承了父类构造函数的属性,没有继承父类原型

2.每个新实例都有父类构造函数的副本,比较臃肿

3. 组合继承(组合原型链继承和借用构造函数继承)
function SubType(name){
    Person.call(this, name) // 构造函数继承
}
SubType.prototype = new Person() // 原型链继承
var sub = new SubType('mom')
console.log(sub.name) // 'mom'
console.log(sub.age) // '10'
特点:

1.结合了两种模式的优点,可继承父类的原型,传参和复用

2.每个新实例引入的构造函数属性是私有的

缺点:

调用了两次父类构造函数(耗费内存),子类的构造函数会替代原型上的那个父类构造函数

4. 寄生组合式继承
function content(obj) {
   function F(){}
    F.prototype = obj // 此处继承了父类的原型
    return new F()
}
var con = content(Person.protype) 
function Sub(name){
    Person.call(this, name) // 继承了父类构造函数的属性
}
Sub.prototype = con // 继承了con实例
con.constractor = Sub // 记得修复构造函数
var sub = new Sub('goodJob')
console.log(sub.age, sub.name) // 10, 'goodJob'

image.png

特点:修复了组合继承的问题