提示:在继续阅读之前,请注意此文章最后更新于 2356 天前,其中的部分内容可能已经无效或过时。

具体代码参考:

准备知识

关于static

static关键字在后端中相信没人陌生,修饰一个字段或者方法时,表示该字段/方法是类的成员而非类所创建的实例的成员。即不能通过类new出来的实例调用。
在javascript中的作用也差不多。大概补充几点:

  • 同一个类中静态方法可以用过this调用其它静态方法/字段
  • 同一类中非静态方法可以用过class(类本身)/this.constructor来调用静态方法/字段。这里补充一点,this.constructor打印出来其实是指类,而不是类里面的构造函数。
  • 类中静态方法中的this指向这个类本身,new Class()等价于new this()
  • 类中非静态方法(包括constructor)指向类创建的实例,因为这些方法属于实例所有
  • 调用静态方法的时候,constructor不会执行
  • 一句话,属于类的成员(静态方法)中的this的指向类,所以可以直接调用其它静态方法/成员。属于类的实例(非静态方法,construtor())的this指向类创建的实例,因此不可以调用静态方法/字段。但可以调用其它实例所有的方法(其它非静态方法)。 栗子:
class StaticExample {
  static _static = 10;

  constructor() {
    console.log('constructor中的this:')
    console.log('this.constructor:', this.constructor);
    console.log(this);
    // console.log(this.A())//error
    // console.log(this.constructor.A()); //可以调用但是死循环,A中调用B,B又会通过constructor调用A
  }

  static A() {
    console.log('1.静态方法B中的this:\t', this)
    console.log('2.静态方法调用静态字段\t', this._static);
    console.log('3.静态方法调用非静态方法B:');
    new this().B();
  }
  B(instance) {
    if (!instance) return;
    console.log(instance === this); //true
    console.log('1.非静态方法B中的this:\t', this)  // 非静态方法指向类创建的实例
    console.log('2.非静态方法用this.contructor调用静态字段\t', this.constructor._static);
    console.log('3.非静态方法用class调用静态字段\t', StaticExample._static);
    this.C();
  }
  C() {
    console.log('1.非静态方法C');
  }
}
StaticExample.A();
let instance = new StaticExample();
instance.B(instance);
class StaticExample {
  static _static = 10;

  constructor(instance) {
    if (!instance) return;
    console.log('constructor中的this:', this) //指向类的实例
    console.log('this.constructor:', this.constructor);//指向类
    console.log(instance === this.constructor);//指向类

  }
}
new StaticExample(new StaticExample().constructor)

补充:在了解this.constructor的过程中,聊着聊着又聊到底层去了,所以要学的还有好多啊。当务之急还是先熟悉react和ts,然后去补充自己的底层基础。

具体实现

首先,在点击按钮中添加点击事件,点击事件会调用类的静态函数,这个类有三个静态函数入口,分别表示正常信息,错误信息,成功信息。以Toast.info为例这个函数接收3个参数,分别是msg:string(信息),duration(延迟),onClose(回调)

Toast.info

这个静态函数只是一个包装,里面调用this._notice,把接收到的参数,加上类型传入进去,即: this._notice('info',msg,duration,onClose);

_notice

这个静态函数里面有两个步骤,第一步是执行_create();这个函数不接收任何参数,作用是创建一个遮罩的DOM元素。之后执行this._ins.addNotice,这个函数是创建真正的提示信息。这里有个不明白的点是,this._ins明明指向类,却能调用非静态addNotice方法。

_create

这个静态函数用于创建一个DOM遮罩,首先检查有没有_ins这个静态字段,如果有,直接返回。如果没有。创建一个DIV元素,zIndex设置为9999,并添加到body的最后。然后通过React.render渲染Toast这个组件,并通过组件上的ref把组件自身存到this._ins中

addNotice

这个非静态函数负责改变state里的值,把传入的参数进行处理后,通过setState进行更新。这个函数还有一个作用是销毁组件,在经过duration秒后,调用_removeNotice并传入notices的key

_removeNotice

这个函数用来在duration秒后销户组件,把notices数组中的每一项进行过滤,如果找到了传入的key对应的消息,就检查这个消息是否携带回调,如果携带,就执行,然后return false过滤掉这一项。之后再通过setState来更新新的消息数组,当数组长度为0的时候,说明遮罩内没有消息了,此时销毁最外层的遮罩容器