JavaScript继承的方法


JavaScript作为一门基于原型的面向对象的动态解释性语言,继承、原型、原型链在其中占据了重要的地位。

前言

文中的重写constructor都使用简单的重新赋值,最好是使用Object.defineProperty(),定义constructor,将其定义为不可配置、不可枚举、不可修改的是比较好的实践

原型链继承
function Person(name){
   this.name=name;
}
function Child(name){
}

Child.prototype=new Person()
Child.prototype.constructor=Child;

缺点:

  1. 没有调用父类构造函数
  2. 假设父类存在引用类型时,所有实例共享这一引用
function Person(name){
   this.arr=[1,2,3]
}
function Child(name){
}

Child.prototype=new Person()
Child.prototype.constructor=Child;

let child1=new Child()
let child2=new Child();

child1.arr.push(5);
console.log(child2.arr);//[1,2,3,5]
构造函数继承

利用call方法调用构造父类构造函数

function Person(name){
   this.arr=[1,2,3]
}
function Child(name){
   Person.call(this,name)
}

优点:

  • 每次实例化,都会新调用父类构造函数,不会存在共享父类引用的问题

缺点:

  1. 所有属性方法都必须在构造函数中设置
  2. 不能访问原型属性,不算严格意义上的继承
组合继承

结合原型链继承和构造函数继承的优点,可以得到组合继承

function Person(name){
   this.arr=[1,2,3]
}
function Child(name){
   Person.call(this,name)
}

Child.prototype=new Person()
Child.prototype.constructor=Child;

let child1=new Child()

优点:

  • 比较好的实现了继承,可以达到基本要求

缺点:

  • 在调用父类构造函数和设置子类原型时调用了两次父类构造函数,存在内存浪费的情况
原型式继承
function createObject(o){
   var Super=function(){};
   Super.prototype=o;
   return new Super();
}

上述函数等效于Object.create()返回对象的原型为传入参数

优点:

  • 不用提前预知子类构造函数

缺点:

  • 子类共享父类引用问题
寄生式继承

在原型继承的基础上添加方法,增强原型继承

function createObject(o){
   var Super=Object.create(o);
   Super.speak=function(){};
   return new Super();
}
寄生组合继承

为了改善组合继承创建两个实例的缺陷,可以利用寄生继承不创建父类实例的优点进行结合

function Person(name){
   this.arr=[1,2,3]
}
function Child(name){
   Person.call(this,name)
}
Child.prototype=Object.create(Person.prototype);
let child1=new Child()

优点:

  • 比较完美

缺点:

  • 稍微复杂了点,但是不是问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值