提示:在继续阅读之前,请注意此文章最后更新于 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);
}
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);
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的时候,说明遮罩内没有消息了,此时销毁最外层的遮罩容器