js中继承关系杂乱?这篇带你理清

原型链继承

  • 每个构造函数都有一个原型对象prototype ,每个实例对象包含一个指向原型对象的指针proto,当代码读取实例的某个属性时,会首先在实例上搜索这个属性,如果没找到,则会去搜索原型对象。
  • 缺点:包含引用类型的值的原型属性会被所有实例共享,如果一个实例改变了这个属性,那么其他实例的该属性也会被改变
js 复制代码
//原型链继承
function Animal(){
    this.arr=[1,2,3]
}
function Cat(){
}
Cat.prototype=new Animal()
var cat1=new Cat()
var cat2=new Cat()
cat1.arr.unshift(4)
console.log(cat1.arr)//[ 4, 1, 2, 3 ]
console.log(cat2.arr)//[ 4, 1, 2, 3 ]
js 复制代码
//原型链继承
----------------写法一
function Animal(name){
    this.name=name
}
Animal.prototype.run=function(){
    console.log(this.name+'跑得快')
}
function Cat(name){
    this.name=name
}
Cat.prototype=new Animal()
var cat1=new Cat("小花")
cat1.run()//小花跑得快
js 复制代码
//原型链继承
----------------写法二
function Animal(){
    this.name="11"
}
Animal.prototype.run=function(){
    return this.name
}
function Cat(){
    this.name="12"
}
Cat.prototype=new Animal()
var cat1=new Cat()
console.log(cat1.run())//12

构造函数继承

  • 构造函数继承,通过使用call或者apply方法,可以在子类中执行父类的构造函数,实现继承
  • 优点:原型属性不会被共享
  • 缺点:不会继承父类prototype上的属性(注意父类的方法还是可以继承的)
js 复制代码
//构造函数继承
function Animal(){
    this.arr=[1,2,3]
}
Animal.prototype.aa="我是父类prototype上的属性"
function Cat(){
    Animal.call(this)
}
var dog=new Animal()
var cat1=new Cat()
var cat2=new Cat()
cat1.arr.unshift(4)
console.log(cat1.arr)//[ 4, 1, 2, 3 ]
console.log(cat2.arr)//[ 1, 2, 3 ]
console.log(dog.aa);//我是父类prototype上的属性
console.log(cat1.aa);//undefined

组合式继承(为了解决构造函数继承无法继承父类prototype的问题)

  • 优点:原型属性不会被共享
  • 可以继承父类的原型链上的属性和方法
  • 缺点:调用了两次父类
  • 在子类的prototype上添加了父类的属性和方法
js 复制代码
//组合式继承
function Animal(){
    this.arr=[1,2,3]
}
Animal.prototype.aa="我是父类prototype上的属性"
function Cat(){
    Animal.call(this)
}
var dog=new Animal()
Cat.prototype=new Animal()--------------在构造函数继承上加入这一行代码
var cat1=new Cat()
var cat2=new Cat()
cat1.arr.unshift(4)
console.log(cat1.arr)//[ 4, 1, 2, 3 ]
console.log(cat2.arr)//[ 1, 2, 3 ]
console.log(dog.aa);//我是父类prototype上的属性
console.log(cat1.aa);//我是父类prototype上的属性

寄生组合继承

  • 优点:原型属性不会被共享
  • 可以继承父类的原型链上的属性和方法
  • 只调用了一次父类,不会在子类的prototype上添加父类的属性和方法
  • 缺点:子类的prototype的原始属性和方法会丢失
  • 解决:放到Object.create后面执行
js 复制代码
//寄生组合继承
function Animal(){
    this.arr=[1,2,3]
}
Animal.prototype.aa="我是父类prototype上的属性"
function Cat(){
    Animal.call(this)
}
Cat.prototype.run=()=>{
    console.log('跑');
}
//创建的是一个没有实例方法的父类实例作为子类的原型
//但是寻找的时候会去有实例方法的父类原型上找
Cat.prototype=Object.create(Animal.prototype)
//指定构造函数的指向
Cat.prototype.constructor=Cat
var cat1=new Cat()
cat1.run()//error
cat1.arr.unshift(4)
console.log(cat1.arr)
相关推荐
不爱吃糖的程序媛40 分钟前
Electron 如何判断运行平台是鸿蒙系统(OpenHarmony)
javascript·electron·harmonyos
Hilaku1 小时前
我用AI重构了一段500行的屎山代码,这是我的Prompt和思考过程
前端·javascript·架构
Cxiaomu1 小时前
React Native App 自动检测版本更新完整实现指南
javascript·react native·react.js
掘金安东尼2 小时前
前端周刊第439期(2025年11月3日–11月9日)
前端·javascript·vue.js
起这个名字2 小时前
微前端应用通信使用和原理
前端·javascript·vue.js
鹏多多3 小时前
Web使用natapp进行内网穿透和预览本地页面
前端·javascript
钱端工程师3 小时前
uniapp封装uni.request请求,实现重复接口请求中断上次请求(防抖)
前端·javascript·uni-app
茶憶3 小时前
uni-app app移动端实现纵向滑块功能,并伴随自动播放
javascript·vue.js·uni-app·html·scss
茶憶3 小时前
uniapp移动端实现触摸滑动功能:上下滑动展开收起内容,左右滑动删除列表
前端·javascript·vue.js·uni-app
Ayn慢慢3 小时前
uni-app PDA焦点录入实现
前端·javascript·uni-app