美文网首页让前端飞Web前端之路前端开发
JS实现继承的几种方式及优缺点

JS实现继承的几种方式及优缺点

作者: 再见那卑微的再见 | 来源:发表于2019-08-21 17:27 被阅读23次

1.原型链继承

实现方式:将子类的原型链指向父类的对象实例

function Parent(){
  this.name = "parent";
  this.list = ['a'];
}
Parent.prototype.sayHi = function(){
  console.log('hi');
}
function Child(){

}
Child.prototype = new Parent();
var child = new Child();
console.log(child.name);
child.sayHi();

原理:子类实例child的__proto__指向Child的原型链prototype,而Child.prototype指向Parent类的对象实例,该父类对象实例的__proto__指向Parent.prototype,所以Child可继承Parent的构造函数属性、方法和原型链属性、方法
优点:可继承构造函数的属性,父类构造函数的属性,父类原型的属性
缺点:无法向父类构造函数传参;且所有实例共享父类实例的属性,若父类共有属性为引用类型,一个子类实例更改父类构造函数共有属性时会导致继承的共有属性发生变化;实例如下:

var a = new Child();
var b = new Child();
a.list.push('b');
console.log(b.list); // ['a','b']

2.构造函数继承

实现方式:在子类构造函数中使用call或者apply劫持父类构造函数方法,并传入参数

function Parent(name, id){
  this.id = id;
  this.name = name;
  this.printName = function(){
    console.log(this.name);
  }
}
Parent.prototype.sayName = function(){
  console.log(this.name);
};
function Child(name, id){
  Parent.call(this, name, id);
  // Parent.apply(this, arguments);
}
var child = new Child("jin", "1");
child.printName(); // jin
child.sayName() // Error

原理:使用call或者apply更改子类函数的作用域,使this执行父类构造函数,子类因此可以继承父类共有属性
优点:可解决原型链继承的缺点
缺点:不可继承父类的原型链方法,构造函数不可复用

3.组合继承

原理:综合使用构造函数继承和原型链继承

function Parent(name, id){
  this.id = id;
  this.name = name;
  this.list = ['a'];
  this.printName = function(){
    console.log(this.name);
  }
}
Parent.prototype.sayName = function(){
  console.log(this.name);
};
function Child(name, id){
  Parent.call(this, name, id);
  // Parent.apply(this, arguments);
}
Child.prototype = new Parent();
var child = new Child("jin", "1");
child.printName(); // jin
child.sayName() // jin

var a = new Child();
var b = new Child();
a.list.push('b');
console.log(b.list); // ['a']

优点:可继承父类原型上的属性,且可传参;每个新实例引入的构造函数是私有的
缺点:会执行两次父类的构造函数,消耗较大内存,子类的构造函数会代替原型上的那个父类构造函数

4.原型式继承

原理:类似Object.create,用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象,结果是将子对象的__proto__指向父对象

var parent = {
  names: ['a']
}
function copy(object) {
  function F() {}
  F.prototype = object;    
  return new F();
}
var child = copy(parent);

缺点:共享引用类型

5.寄生式继承

原理:二次封装原型式继承,并拓展

function createObject(obj) {
  var o = copy(obj);
  o.getNames = function() {
    console.log(this.names);
    return this.names;
  }
  return o;
}

优点:可添加新的属性和方法

6.寄生组合式继承

原理:改进组合继承,利用寄生式继承的思想继承原型

function inheritPrototype(subClass, superClass) {
  // 复制一份父类的原型
  var p = copy(superClass.prototype);
  // 修正构造函数
  p.constructor = subClass;
  // 设置子类原型
  subClass.prototype = p;
}

function Parent(name, id){
  this.id = id;
  this.name = name;
  this.list = ['a'];
  this.printName = function(){
    console.log(this.name);
  }
}
Parent.prototype.sayName = function(){
  console.log(this.name);
};
function Child(name, id){
  Parent.call(this, name, id);
  // Parent.apply(this, arguments);
}
inheritPrototype(Child, Parent);

相关文章

  • JS实现继承的几种方式及优缺点

    1.原型链继承 实现方式:将子类的原型链指向父类的对象实例 原理:子类实例child的__proto__指向Chi...

  • 聊一聊js的几种继承方式

    在js中, 很多地方需要使用到继承, 废话少说, 今天来聊一聊js几种继承方式的优缺点 构造函数继承functio...

  • 前端菜鸟成长记(三)之answer

    关于上次作业的答案 js有几种实现继承的方法(我直接给答案,原型链继承,借用构造函数继承,组合继承)?各自的优缺点...

  • JS篇

    1、js继承的几种方式 优缺点特别清楚https://www.cnblogs.com/cjr001/p/7241...

  • 二、js继承的几种方式及优缺点

    1、继承:原型链、借用构造函数、组合继承、原型式继承、寄生式继承、寄生组合继承

  • 03.js中的继承

    # 概述 本文主要记录js中实现继承的几种方法的实现,优缺点分析 # 知识铺垫 + **构造函数,原型和实例的关系...

  • JS实现继承的几种方式

    https://www.cnblogs.com/humin/p/4556820.html

  • js实现继承的几种方式

    JS继承的实现方式:既然要实现继承,那么首先我们得有一个父类,代码如下: 1、原型链继承核心: 将父类的实例作为子...

  • JS实现继承的几种方式

    转自 https://www.cnblogs.com/humin/p/4556820.html 前言 JS作为面向...

  • js实现继承的几种方式

    如何实现继承? js中实现继承的方式主要是通过原型链完成的。了解原型链的相关信息可以点这里 javascript中...

网友评论

    本文标题:JS实现继承的几种方式及优缺点

    本文链接:https://www.haomeiwen.com/subject/cmabsctx.html