首页 > 其他分享 >【JS】类继承

【JS】类继承

时间:2022-10-28 22:25:05浏览次数:53  
标签:run name 继承 JS say constructor super man

类继承:         - 可以实现一个类扩展另一个类         - 使用extends关键字进行类继承             class Child extends Parent                 1. extends内部机制            - 使用原型机制,Child.prototype.[[Prototype]] = Parent.prototype          - 子类可以访问父类的方法

class Animal{
    constructor(name){
        this.name = name
    }
    run(){
        console.log('animal run');
    }
}

class Dog extends Animal{

}

let d = new Dog('dog')
d.run() // 'animal run'
        2.方法重写             2.1 完全重写             
class Animal{
    constructor(name){
        this.name = name
    }
    run(){
        console.log('animal run');
    }
}

class Dog extends Animal{
    run(){
        console.log('dog run');
    }
}

let d = new Dog('dog')
d.run() // 'dog run'
            2.2 方法扩展                 - 当不希望完全重写父类方法时,可以使用super关键字,执行super.method()来调用一个父类的方法
class Animal{
    constructor(name){
        this.name = name
    }
    run(){
        console.log('animal run');
    }
}
class Dog extends Animal{
    run(){
        super.run()
        console.log('dog run');
    }
}
let d = new Dog('dog')
d.run() // 'animal run' 'dog run'
        * 箭头函数没有super           3. constructor重写             - 若子类不写自己的constructor,则默认会有一个空的constructor,里面有super(),也就是调用了父类的constructor,并将所有参数传了进去。             类似这样:             class Dog extends Animal{                 constructor(...args){                     super(...args)                 }             }      - 执行super(...args)可以调用父类的constructor              - 若子类写了constructor,需要在this语句前调用super(),否则会报错:             Must call super constructor in derived class before accessing 'this' or returning from derived constructor             在访问“this”或从派生构造函数返回之前,必须在派生类中调用super               原因:                 JS中继承类的构造函数中有一个特殊的属性[[Constructorkind]]:"derived",这个内部标签会影响它的new行为,让继承类中的constructor无法正常工作,普通函数使用new时,会创建一个空对象并将this指定为该对象,但在这里继承类使用new时,类中的constructor不会这样做,而是期待父类中的constructor来完成这项操作。

 

        4.类字段重写             父类构造器中只会使用自己字段的值,而不是重写的             原因:                 类字段初始化的顺序不一样                 - 对于基类,在调用构造函数前初始化                 - 对于派生类,则是在调用完super()后才进行初始化                             所以,new Dog()后要执行Dog中constructor函数,所以会先执行super调用父类中的constructor。执行父类的constructor时,父类中字段已经初始化好了,但子类还没有,所以使用时会使用父类中的字段。

 

        5.super原理             当一个对象方法执行时,它会将当前对象作为 this。随后如果我们调用 super.method(),那么引擎需要从当前对象的原型中获取 method。但仅仅依靠this无法实现,有时this指向的对象不是我们想要的。

 

            JavaScript中在函数中有一个特殊的内部属性[[HomeObject]],当一个函数被定义为类或对象中的方法时,该函数中的[[HomeObject]]属性就成为该对象。然后super就使用它接卸父原型及其方法。
const person = {
    name: 'person',
    say(){
        console.log(this.name,'say');
    }
}

const man = {
    __proto__: person,
    name:'man',
    say(){ // man.say.[[HomeObject]] == man
        super.say()
    }
}
man.say()
            在 JavaScript 语言中 [[HomeObject]] 仅被用于 super。所以,如果一个方法不使用 super,那么我们仍然可以视它为自由的并且可在对象之间复制。            
const person = {
    name: 'person',
    say(){
        console.log(this.name,'person say');
    }
}

const man = {
    __proto__: person,
    name:'man',
    say(){ // man.say.[[HomeObject]] == man
        super.say()
    }
}
man.say()

const animal = {
    name:'animal',
    say(){
        console.log(this.name,'animal say');
    }
}

const cat = {
    __proto__: animal,
    name:'cat',
    say: man.say
}

cat.say() //cat person say 
              cat中的say: man.say == { // man.say.[[HomeObject]] == man                     super.say()                 }             由于有super,所以会找[[HomeObject]],此时的[[HomeObject]]是man,因为是在man中创建的,[[HomeObject]]已经被永久绑定了。所以会找man对象原型上的say方法。               [[HomeObject]] 是为类和普通对象中的方法定义的。但是对于对象而言,方法必须确切指定为 method(),而不是 "method: function()"。

标签:run,name,继承,JS,say,constructor,super,man
From: https://www.cnblogs.com/ahoge/p/16837691.html

相关文章

  • 今天,念念不忘一件事... ✅FastJson在调用JSON#toJSONString时,如何截取比较长的value串
    项目里前后端页面的http请求及dubbo服务间的RPC调用,返回值类型统一是一个Result<T>,其结构如下。@DatapublicclassResult<T>implementsSerializable{priv......
  • JavaScript--JSONP和Axios
    JSONP概述:JSONP(JSONwithpadding)是一种跨域解决方案,它主要是利用了script标签不受跨域影响的特性来完成对应的请求操作。实际上是一个get请求。JSONP格式包含两个部分:......
  • JS中数值类型的本质
    一、JS中的数值类型众所JS爱好友周知,JS中只有一个总的数值类型——number,它包含了整型、浮点型等数值类型。其中,浮点数的实现思想有点复杂,它把一个数拆成两部分来存储。第......
  • PYTHON JSON EXCEL
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#pipinstallpandas#pipinstallopenpyxl#importjsonimporttimeimportpandasimpor......
  • JS删除两个数组对象中id相同的对象
    letarr1=[{id:'1',name:'json'},{id:'2',name:'book'}]letarr2=[{id:'1',name:'json',age:'15'},{id:'2',name:'book',age:'16'},{id:'3',name:'......
  • js一键切换dark模式 -
    js一键切换dark模式//初始化$(function(){lettheme=$.cookie('theme');if(theme=="dark"){$("body").addClass('dark');$("#theme").add......
  • 【JS】大道至简---来看看JS中你最熟悉的变量和数值的知识吧
    1变量1.1什么是变量?变量就是一个装东西的盒子。变量是用于存放数据的容器。我们通过变量名获取数据,数据可以被更改。1.2声明变量1.2.1定义单个变量js通过var来声明变量,v......
  • VSCode-Add_Configuration后launch.json为空的解决办法
    VSCode-AddConfiguration后launch.json为空的解决办法今天需要使用VSCodedebug一个程序,点击菜单栏的“Run”-"AddConfiguration"选项,准备生成一个默认的launch.json......
  • 模拟腾讯返回的json数据
     模拟腾讯返回的json数据 $(document).ready(function(){$("#SubmitButton").click(function(){alert("ajax准备......
  • 腾讯返回json数据转换
     腾讯返回json数据转换 #region----远程获取微信小程序二维码的流----///<summary>///远程获取微信小程序二维码的流///</summary>......