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)
相关推荐
盛夏绽放1 小时前
jQuery 知识点复习总览
前端·javascript·jquery
大怪v3 小时前
超赞👍!优秀前端佬的电子布洛芬技术网站!
前端·javascript·vue.js
项目題供诗4 小时前
React学习(十二)
javascript·学习·react.js
无羡仙4 小时前
Webpack 背后做了什么?
javascript·webpack
码哥DFS5 小时前
NPM模块化总结
前端·javascript
灵感__idea5 小时前
JavaScript高级程序设计(第5版):代码整洁之道
前端·javascript·程序员
唐璜Taro6 小时前
electron进程间通信-IPC通信注册机制
前端·javascript·electron
陪我一起学编程7 小时前
创建Vue项目的不同方式及项目规范化配置
前端·javascript·vue.js·git·elementui·axios·企业规范
Summer不秃8 小时前
uniapp 手写签名组件开发全攻略
前端·javascript·vue.js·微信小程序·小程序·html
coderklaus8 小时前
Base64编码详解
前端·javascript