继承在ES5和ES6中实现

文章详细阐述了JavaScript中的原型概念,包括__proto__属性、构造函数、原型链以及不同类型的继承方式,如原型链继承、构造函数继承、组合式继承、寄生组合式继承和圣杯模式继承。此外,还介绍了ES6中的class语法和继承机制,以及如何通过mixin实现类似多继承的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原型

创建对象的方法

let obj = {}
let obj1 = Object.create(obj)
let obj2 = new Object(obj1)
function M(){} let obj3 = new M()

原型详解

Javascript中每一个对象都有自己的特殊内置属性**[[prototype]]**,这个特殊属性可以指向另一个对象
获取方式
可以通过实例对象的__proto__属性可以获取到。

let obj = {}
obj.__proto__ === Object.getPrototypeOf(obj) //true

在这里插入图片描述
该图为构造函数和原型对象,实例对象的关系

constructor

该属性在对象创建时就在prototype中存在
该属性不可遍历,但是可以通过属性描述符改变属性,使其可以遍历

Object.defineProperty(Super.prototype,'constructor',{
    enumerable:true,
    configurable:true,
    writable:true,
    value:Super
})
console.log(Object.keys(sub))

原型链

在这里插入图片描述
总结:所有函数都是function的实例,所有原型对象都是Object()的实例。原型链又叫隐式原型链,由__proto__串联而成

ES5中实现继承

原型链继承

在这里插入图片描述
这里可看到,sub继承了Super上的属性
弊端:引用值共享问题,引用值sub1改变后sub上也改变了。

构造函数继承

在这里插入图片描述
引用值共享问题解决
**弊端:**无法继承到父亲原型上的方法

组合式继承(伪经典继承)

在这里插入图片描述

弊端 : new Super() 和 Super.call执行了两次 ,性能损失

寄生组合式继承

在这里插入图片描述
性能损失解决
弊端:重写了Sub.prototype,使得实例化对象无法调用方法

圣杯模式继承

function inherit(Target,Origin){
    function F(){}
    F.prototype = new F();
    Target.prototype = F.prototype
    Target.prototype.constructor = Target
    Target.prototype.uber = Origin.prototype
}

圣杯模式在子类和父类中定义了一个中间类,这样改变子类上的prototype上的变量就不会影响到父类的prototype,因为他们不共享原型。
雅虎高级写法,使用闭包私有化变量

const inheritYaHU = (function (){
    var F = function (){}
    return function (Target,Origin){
        F.prototype = Origin.prototype
        Target.prototype = new F();
        Target.prototype.constructor = Target
        Target.prototype.uber = Origin.prototype
    }
}())

ES6中实现继承

class

内部操作
当我们通过new关键字操作类的时候,会调用这个constructor函数,并且执行如下操作:
◻ 1.在内存中创建一个新的对象(空对象);
◻ 2.这个对象内部的[[prototype]]属性会被赋值为该类的prototype属性;
◻ 3.构造函数内部的this,会指向创建出来的新对象;
◻ 4.执行构造函数的内部代码(函数体代码);
◻ 5.如果构造函数没有返回非空对象,则返回创建出来的新对象;

类似于java,可以使用extends继承

class Father {
    constructor(){
        this.name = 'jth'
    }
    static say(name){
        console.log(name)
    }
    sayName(){
        console.log('wolf')
    }
}

class Son extends Father{
    constructor(){
        //调用父类方法
        super().sayName();
    }
}

let son = new Son()
console.log(son.name)

也可以继承内置类
js不支持多继承,可以使用mixin进行继承,使用父类方法

// JavaScript只支持单继承(不支持多继承)
function mixinAnimal(BaseClass) {
  return class extends BaseClass {
    running() {
      console.log("running~")
    }
  }
}

function mixinRunner(BaseClass) {
  return class extends BaseClass {
    flying() {
      console.log("flying~")
    }
  }
}

class Bird {
  eating() {
    console.log("eating~")
  }
}

// var NewBird = mixinRunner(mixinAnimal(Bird))
class NewBird extends mixinRunner(mixinAnimal(Bird)) {
}
var bird = new NewBird()
bird.flying()
bird.running()
bird.eating()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值