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)
相关推荐
萑澈17 小时前
Windows 7 运行 Electron 安装包报“不是有效的 Win32 应用程序”怎么办
javascript·windows·electron
W.A委员会17 小时前
JS原型链详解
开发语言·javascript·原型模式
她说彩礼65万18 小时前
C# 实现简单的日志打印
开发语言·javascript·c#
状元岐19 小时前
C#反射从入门到精通
java·javascript·算法
a11177620 小时前
Three.js 的前端 WebGL 页面合集(日本 开源项目)
前端·javascript·webgl
Kk.080220 小时前
项目《基于Linux下的mybash命令解释器》(一)
前端·javascript·算法
程序员鱼皮21 小时前
又一个新项目开源,让 AI 帮你盯全网热点!
javascript·ai·程序员·编程·ai编程
MXN_小南学前端21 小时前
前端开发中 try...catch 到底怎么用?使用场景和最佳实践
javascript·vue.js
星空椰21 小时前
JavaScript 基础进阶:分支、循环与数组实战总结
开发语言·javascript·ecmascript