资讯专栏INFORMATION COLUMN

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

ymyang / 3431人阅读

摘要:原型继承缺点子类实例共享属性,造成实例间的属性会相互影响可以看到子类的实例属性皆来自于父类的一个实例,即子类共享了同一个实例共享了父类的方法构造函数继承缺点父类的方法没有被共享,造成内存浪费子实例的属性都是相互独立的实例方法也是独立的,没有

原型继承

缺点: 子类实例共享属性,造成实例间的属性会相互影响

function Parent1() {
  this.name = ["super1"]
  this.reName = function () {
    this.name.push("super111")
  }
}
function Child1() {

}
Child1.prototype = new Parent1()
var child11 = new Child1()
var child12 = new Child1()
var parent1 = new Parent1()
child11.reName()
console.log(child11.name, child12.name) // [ "super1", "super111" ] [ "super1", "super111" ], 可以看到子类的实例属性皆来自于父类的一个实例,即子类共享了同一个实例
console.log(child11.reName === child12.reName) // true, 共享了父类的方法
构造函数继承

缺点: 父类的方法没有被共享,造成内存浪费

function Child2() {
  Parent1.call(this)
}

var child21 = new Child2()
var child22 = new Child2()
child21.reName()
console.log(child21.name, child22.name) // [ "super1", "super111" ] [ "super1" ], 子实例的属性都是相互独立的
console.log(child21.reName === child22.reName) // false, 实例方法也是独立的,没有共享同一个方法
组合继承

缺点: 父类构造函数被调用两次,子类实例的属性存在两份。造成内存浪费

function Parent3() {
  this.name = ["super3"]
}
Parent3.prototype.reName = function() {
  this.name.push("super31")
}
function Child3() {
  Parent3.call(this) // 生成子类的实例属性(但是不包括父对象的方法)
}
Child3.prototype = new Parent3() // 继承父类的属性和方法(副作用: 父类的构造函数被调用的多次,且属性也存在两份造成了内存浪费)
var child31 = new Child3()
var child32 = new Child3()
child31.reName()
console.log(child31.name, child32.name) // [ "super3", "super31" ] [ "super3" ], 子类实例不会相互影响
console.log(child31.reName === child32.reName) //true, 共享了父类的方法
寄生继承

完美:子类都有各自的实例不会相互影响,且共享了父类的方法

function Parent4() {
  this.name = ["super4"]
}
Parent4.prototype.reName = function() {
  this.name.push("super41")
}
function Child4() {
  Parent4.call(this) // 生成子类的实例属性(但是不包括父对象的方法)
}
Child4.prototype = Object.create(Parent4.prototype) // 该方法会使用指定的原型对象及其属性去创建一个新的对象
var child41 = new Child4()
var child42 = new Child4()
child41.reName()
console.log(child41.name, child42.name) //[ "super4","super41" ] [ "super4" ], 子类实例不会相互影响
console.log(child41.reName === child42.reName) //true, 共享了父类的方法
ES6 class

和寄生继承实现的效果一致

class Parent5 {
  constructor() {
    this.name = ["super5"]
  }
  reName() {
    this.name.push("new 5")
  }
}

class Child5 extends Parent5 {
  constructor() {
    super()
  }
}

var child51 = new Child5()
var child52 = new Child5()
child51.reName()
console.log(child51.name, child52.name) // [ "super5", "new 5" ], 子类实例不会相互影响
console.log(child51.reName === child52.reName) //true, 共享了父类的方法

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91771.html

相关文章

  • 一名【合格】前端工程师的自检清单

    摘要:在他的重学前端课程中提到到现在为止,前端工程师已经成为研发体系中的重要岗位之一。大部分前端工程师的知识,其实都是来自于实践和工作中零散的学习。一基础前端工程师吃饭的家伙,深度广度一样都不能差。 开篇 前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,技术迭代速度之快是其他技术所不能比拟的。 winter在他的《重学前端》课程中提到: 到现在为止,前端工程师已经成为研...

    罗志环 评论0 收藏0
  • 一名【合格】前端工程师的自检清单

    摘要:在他的重学前端课程中提到到现在为止,前端工程师已经成为研发体系中的重要岗位之一。大部分前端工程师的知识,其实都是来自于实践和工作中零散的学习。一基础前端工程师吃饭的家伙,深度广度一样都不能差。开篇 前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,技术迭代速度之快是其他技术所不能比拟的。 winter在他的《重学前端》课程中提到: 到现在为止,前端工程师已经成为研发体系...

    isaced 评论0 收藏0
  • 史上最全阿里 Java 面试题总结

    摘要:以下为大家整理了阿里巴巴史上最全的面试题,涉及大量面试知识点和相关试题。的内存结构,和比例。多线程多线程的几种实现方式,什么是线程安全。点击这里有一套答案版的多线程试题。线上系统突然变得异常缓慢,你如何查找问题。 以下为大家整理了阿里巴巴史上最全的 Java 面试题,涉及大量 Java 面试知识点和相关试题。 JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节。 S...

    winterdawn 评论0 收藏0
  • 面试--js实现继承几种方式

    摘要:基于原型的继承原型上的属性被共享了不是我们所需要的这种继承会有如下的缺点如果父类包含有引用类型的属性所有的子类就会共享这个属性。 基于原型的继承 function father() { this.faName = father; this.names=[11,22] } father.prototype.getfaName = fun...

    baiy 评论0 收藏0
  • javascript 面向对象(实现继承几种方式)

    摘要:老明调用了从原型中继承来的方法继承到了当前对象的原型中调用了从原型中扩展来的方法构造继承基本思想借用构造函数的基本思想就是利用或者把父类中通过指定的属性和方法复制借用到子类创建的实例中。 1、原型链继承 核心: 将父类的实例作为子类的原型 缺点: 父类新增原型方法/原型属性,子类都能访问到,父类一变其它的都变了 function Person (name) { ...

    liujs 评论0 收藏0

发表评论

0条评论

ymyang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<