JS 实现继承的几种方式

news/2024/9/23 5:22:19/

现在有parent、child两个函数,child函数的实例想要访问parent函数的属性和方法(child想要继承parent)。

1、原型链继承

缺点:有引用的值共享的问题

即当parent某个属性是引用数据类型的时候,child实例如果修改了这个属性的内容则其他的child实例中这个属性也会一起改变(正常来说应该是互不干扰的,原始数据类型属性就是互不干扰的)

function parent(){this.data = '我是parent'
}function child(){}child.prototype = new parent()var fun = new child()console.log(fun.data)

2、构造函数集成

通过在child函数中独立执行parent( 此时parent的this指向window ),然后通过call方法改变parent的指向指向child实例( parent.call(this) ),这样new出来的child实例就能访问到parent中的属性和方法了。这种方法就称为构造函数继承。

缺点:使用这种方法child实例没有办法拿到parent函数原型上的属性和方法。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}var fun = new child()console.log(fun.data)        // 输出“我是parent”
fun.say()                    // 此处报错

3、组合继承(构造函数+原型链)

这个方法是结合了上述的两个方法:

  • 用构造函数继承中的child函数独立执行parent来解决原型链继承的引用值共享问题
  • 用原型链继承中child函数的原型指向parent的实例来解决构造函数中child实例无法访问parent原型上属性和方法的问题。

 缺点:new了两次parent,会产生了属性与方法重叠的问题。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}child.prototype = new parent()var fun = new child()console.log(fun.data)
fun.say()

 4、寄生组合继承(经典继承)

(第三种方法)组合继承:无论什么情况下,都会调用两次父类的构造函数。寄生组合式继承就解决了上述问题,被认为是最理想的继承方式。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}child.prototype = Object.create(parent.prototype)var fun= new child()console.log(fun.data)
fun.say()

5、原型式继承

原型式继承是一种基于已有对象创建新对象的继承方式,适用于简单对象的继承。在 JavaScript 中可以使用 Object.create 方法来实现原型式继承。

// 原型对象
var parent = {name: 'parent',age: 30,say: function () {return '我是' + this.name}
}// 基于原型对象创建新对象
var child= Object.create(parent)child.name = 'Alice'   // 修改属性值
child.age = 25         // 修改属性值console.log(child.say()) // 输出 "我是 Alice"

6、es6的extends类继承 

 child类通过extends继承了parent类的属性和方法。

class Parent {constructor(name) {this.name = name}// 原型方法// 即 Parent.prototype.getName = function() { }// 下面可以简写为 getName() {...}getName = function () {console.log('Parent:', this.name)}
}
class Child extends Parent {constructor(name, age) {// 子类中存在构造函数,则需要在使用“this”之前首先调用 super()。super(name)this.age = age}
}
const asuna = new Child('Asuna', 20)
asuna.getName() // 成功访问到父类的方法


http://www.ppmy.cn/news/1458043.html

相关文章

【算法练级js+java】重复给定字符n次

题目 Repeats the given string n times.(复制指定的字符串n次) 期望结果 /** * Repeats the given string n times. * * repeat(‘, 3) * // > **’ * * repeat(‘abc’, 2) * // > ‘abcabc’ * * repeat(‘abc’, 0) * // > “” **/ 代码…

护眼台灯哪个牌子最好?618五款护眼台灯品牌推荐

在光照不足的环境中,护眼台灯还能提升阅读和学习的视觉舒适度,减轻眼疲劳和视觉疲劳的可能性。鉴于当今儿童和青少年的学习用眼时间较长,而且他们处于视力发展的关键阶段,眼瞳更为敏感,容易发生近视,因此&a…

专业软件测试会议

全国软件测试会议:这是一个系列性的专业会议,由中国的学术机构或专业组织主办,例如中国计算机学会的容错计算专业委员会。此会议自2005年起开始举办,历届会议地点包括北京、昆明和武汉等地。会议内容覆盖软件测试理论、实践、工具…

GO语言核心30讲 进阶技术 (第二部分)

原站地址:Go语言核心36讲_Golang_Go语言-极客时间 一、接口类型的合理运用 1. 接口类型只包含方法,不包含字段。 方法集合就是它的全部特征。 任何数据类型,只要实现了接口的方法集合全部,那么它就是这个接口的实现类型 2. 怎么…

网络安全之DHCP详解

DHCP:Dynamic Host Configration Protocol 动态主机配置协议 某一协议的数据是基于UDP封装的,当它想确保自己的可靠性时,这个协议要么选确认重传机制,要么选周期性传输。 DHCP是确认重传,【UDP|DHCP】,当DHCP分配完地…

Spring中用到的设计模式有哪些

工厂模式,BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象。 单例模式,Spring依赖注入Bean实例默认是单例的。Spring依赖注入(包括lazy-init方式)都是发生在AbstractBeanFactory的getBean里。getBean的doGetBean方法调用getSingleton进行bean的创…

在python中对Requests的理解

离上次写文章已经有小半个月了,但是: 没有动态的日子里,都在努力生活❤️;发表动态的日子里,都在热爱生活。🌹 目录 一、python集成工具的分类:1.解释Requests2. Requests3. Response对象的属性…

用户至上!探索7种常用的用户体验研究方法

用户体验研究是产品开放过程中的重要组成部分,优秀的产品设计与高质量的用户体验是不可分割的。对于产品开发,选择合适的用户体验研究方法在很大程度上决定了产品的使用效果。本文全面阐述了用户体验研究、用户体验研究的重要性和用户体验研究方法&#…