• 11.新增class


    1.Class简介


    class Person{
      constructor(name, id){
        this.name = name
        this.id = id
      }
      toString(){
        return `${name}: ${id}`
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.1 class特性

    • 本质上是一个函数
    • 默认严格模式
    • 不存在提升行为
    • name属性是class关键字后面的类名
    • 内部[Symbol.iterator]表示Generator函数

    在类中的方法都会定义在prototype上面

    class Person{
      constructor(name, id){
        this.name = name;
        this.id = id;
      }
      toString(){
        return `${this.name}: ${this.id}`
      }
      toValue(){
        return this.id
      }
    }
    Object.getOwnPropertyNames(Person.prototype)  // ['constructor','toString','toValue']
    
    
    // 等同于
    Person.prototype = {
      constructor() {},
      toString() {},
      toValue() {},
    }
    Object.defineProperty(Person.prototype,'constructor',{
      value: Person,
      writable:false,
      enumerable: false, // 不可枚举喔~
      configurable: false
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    类的getter/setter

    class Person {
      constructor(name, id) {
        this.name = name
        this.id = id
      }
      get _id() {
        return this.id + 1
      }
      set _id(value){
        this.id = value
      }
    }
    const p = new Person('jack', 107)
    console.log(p._id)  // 108
    console.log(p.id)  // 107
    p._id = 100
    console.log(p.id) // 100
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    this默认指向类实例,但是单独抽离出来会出现错误

    class Person {
      constructor(name){
        this.name = name
      }
      sayName(){
        this.print(this.name)
      }
      print(text){
        console.log(text);
      }
    }
    const p = new Person('jack')
    p.sayName() // jack
    // 抽离出来
    const{sayName} = p
    sayName() // print is not defined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    改进

    constructor(name){
      this.name = name
      this.sayName = this.sayName.bind(this)
    }
    
    • 1
    • 2
    • 3
    • 4

    2.Class静态方法


    在一个方法前加上static关键字时,会定义方法在类上而非原型上,称为静态方法,即静态方法是供类调用的,非静态方法是供实例调用的

    class Foo {
      static classMethod() {
        return 'hello'
      }
    }
    
    Foo.classMethod() // 'hello'
    
    var foo = new Foo()
    foo.classMethod() // TypeError: foo.classMethod is not a function
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在static静态方法中,this指向的是类,而非实例,同时静态方法名可以与非静态方法名重名

    class Foo {
      static bar() {
        this.baz()
      }
      static baz() {
        console.log('class')
      }
      baz() {
        console.log('instance.prototype')
      }
    }
    Foo.bar() // class
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    可以通过super关键字访问父类,以访问到父类中的静态方法

    class Foo {
      static fn() {
        return 'hello'
      }
    }
    
    class Bar extends Foo {
      static fn() {
        return super.fn() + ', too'
      }
    }
    
    Bar.fn() // "hello, too"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.Class实例、原型、静态属性方法定义


    不多bb了,直接上代码

    class Person{
      constructor(name){ 
    	this.name = name // instance.name
      }
      id=1008 // instance.id
      sayId = function(){ return this.id}// instance.sayId
      
      sayName(){ return this.name} // prototype.sayName
      get name(){ return 'jack' } // prototype.name (getter/settter)
      set name(newVal,oldVal){
    	this.name = newVal
    	console.log(`new:${newVal},old:${oldVal}`)
      }
      
      static cId = 1007 // constructor.cId
      static sayHello(){ return 'hello' } // constructor.sayHello
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    4.静态块


    ES2022引入了静态块,允许在类的内部设置一个代码块,在类生产时运行一次,主要用于对静态属性的初始化

    class C {
      static x = ...;
      static y;
      static z;
    
      static {
        let obj = doSomethingWith(this.x)
        this.y = obj.y
        this.z = obj.z
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5.Class继承


    5.1 extends关键字

    在定义子类时,使用extends关键字指定其父类,在子类内部通过super指向父类,super()方法调用父类的constructor

    class Father {
      constructor(name, id) {
        this.name = name
        this.id = id
      }
      fn1() { ... }
      static fn2(){ ... }
    }
    class Son extends Father {
      constructor(name, id, age) {
        super(name, id) // 调用父类的constructor
        this.age = age
      }
      fn1() {
        return super.fn1() + this.age // 调用父类的fn1()
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    注意: 子类必须在constructor()构造方法中调用super()方法来完成构造,从而获得与父类同样的实例属性和方法,再对其进行扩展

    若子类没有定义constructor方法会默认添加

    class Son extends Father{}
    //等同于
    class Son extends Father{
      constructor(...args){
        super(...args)
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    由于调用super方法,才能通过父类的构造函数创建子类实例,故this(指向子类实例)要在super后才有定义

    class Point {
      constructor(name, id) {
        this.name = name
        this.id = id
      }
    }
    
    class ColorPoint extends Point {
      constructor(name, id, color) {
        this.color = color // ReferenceError
        super(name, id) // 通过父类构造函数创建子类实例
        this.color = color // 正确
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.2 super关键字

    在子类构造函数中必须要先调用super(),这时候会执行父类构造函数,并将this执行创建的子类实例

    class A {
      constructor() {
        console.log(new.target.name)
      }
    }
    class B extends A {
      constructor() {
        super()
      }
    }
    new A() // A
    new B() // B
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    Angular 依赖注入介绍及使用(五)
    python开发之个微群聊机器人的开发
    前端面试题-javascript
    Netty中ctx.channel().close()与ctx.close的区别
    IntelliJ IDEA - Github Copilot Waiting for Authorization [一篇必解决]
    JS之简易deepCopy(简介递归)
    牛牛的等差数列(思维 + 线段树)
    GenAI的“关键一跃”:推理与知识
    【技术积累】算法中的基本概念【一】
    十六、【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构之Eclipse 运行程序
  • 原文地址:https://blog.csdn.net/Xiaoyc7/article/details/125538824