JS实现继承的六种方式

1.原型链继承

        简单来说就是让一个实列对象的__proto__属性(构造器函数的prototype属性)指向另外一个对象的实列,从而达到前一个实列对象能够使用后一个实列对象种的属性和方法。

        代码说明

 function Father() {
      this.name = "jack"
    }
    const f = new Father()
    function Son() {
      this.sonname = "rose"
    }
    Son.prototype = f
    const s = new Son()
    console.log(s.name); //jack
    console.log(s.sonname);  //rose

     在实例s中 并没有name属性,这边打印出jack是因为继承了Father的实列对象种的name属性。

这里注意更换Son.prototype属性需要在创建Son实例之前,否则无法继承Father中的name属性

画图说明

  1.这是没有修改Son的protootype属性之前原型图

 2.修改之后

优点:写法简单,容易理解

缺点:

        1.对象实例共享所有继承的属性和方法,一个对象修改继承的属性和方法,所有实例对象都会修改

        2.创建实例对象时,无法传递参数,因为子类无法使用父类的构造器传参

2.构造参数继承

 function Fanther(name) {
      this.name = name
    }

    function Son(sonname) {
      Fanther.apply(this, [sonname])
    }
    const s = new Son("jack")

    console.log(s.name); //jack
    console.log(s.sonname); //undefined
    const s2 = new Son("rose")

    console.log(s2.name); //rose

在子构造函数当中使用call()、apply()、bind()方法修改this的指向,这里修改的时Father构造函数当中的this指向,指向为子对象实例

画图说明

 

 修改this指向后,子类实例也可以继承父类构造函数当中的属性和方法,而不能继承父类构造函数原型对象中的属性和方法

优点:可以给父类构造器传递参数,每个实例对象中的属性和方法都是独有的,不和其他对象共享

缺点:不能继承父类构造器原型对象中的属性和方法

3.组合继承

组合继承是由原型链继承和构造函数继承的组合继承,解决了原型链中不能给父类构造函数传参的问题,也解决了构造函数继承中不能继承原型对象成员的问题

function Father(name) {

    }
    function Son(sonname) {
      Father.call(this, name)
    }
    const f = new Father()
    Son.prototype = f
    const s = new Son()

这样s实例对象即可以给父类构造函数传参,也可以继承父类构造函数原型对象上的成员

画图说明

4.原型式继承

说到原型式继承,则必须要引用Object构造函数上的静态方法 Object.create()。该方法可以传一个参数,创建出来的对象会以该参数为原型对象来创建。

Object.create()底层代码

function object(obj){
    function F(){}        //创建一个构造函数
    F.prototype = obj;    //将传进来的参数对象重写构造函数的原型
    return new F();       //返回出去一个F构造函数的实例对象
}
var person = {
    name:'阿轩',
    age:'20',
}
var obj = Object(person);

在来看代码

const father = {
      name: "jack",
      age: 16

    }
    const son = Object.create(father)
    console.log(son.__proto__.__proto__.constructor);

和原型链继承存在关联

画图说明

缺点:引用类型的属性会被所有对象实例共享

5.寄生式继承

这种继承方法相当于对原型链继承的一种增强,给原型式继承方法添加一个功能,可以往对象上额外添加属性和方法

function createChild(parent) {
const child = Object.create(parent);
child.name = 'Child';
child.sayHello = function() {
console.log(`Hello, I'm ${this.name}`);
};
return child;
}

const parent = {
name: 'Parent'
};

const child = createChild(parent);
child.sayHello(); // 输出 "Hello, I'm Child"

画图说明

6.寄生组合式继承

这种继承方式式构造函数继承和原型式继承的组合,变相解决了原型式继承成员被所有对象

function SuperType(age){
    this.color = 'red';
    this.age = age;
}
SuperType.prototype.name = '阿轩';


function Type(age){
    SuperType.call(this,age);    //绑定this
}
Type.prototype = Object.assign(Type.prototype,SuperType.prototype) 
Type.prototype.constructor = Type
var type = new Type(18);

console.log(instance.color)
console.log(instance.name)
console.log(instance.age)

 这里用 Object.assign 去代替了 Object.create ,把父类的原型融入到子类的原型上,且以对象的形式放到 Type 的原型上,且这些原型一般是不会发生改变的,故即引用类型的属性始终会被继承所共享也是没有关系的,变相的解决了这些问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值