ES6 下实现静态方法间的相互调用
成龙大哥突然来问我一个前端问题,他问:
使用 ES6 的类,类中有两个方法彼此会相互调用,那怎么办?
听到这个问题的时候,我是一头雾水的,不是用 this
就好了吗。
然后他就给了个场景,让我来怼。
场景伪代码
照着大哥的想法,我撸了一个伪代码。
1 | class Fetch{ |
可以看到就一个类 Fetch
,里面有两个静态方法——检查返值
和 get
。
类的外面只有一行代码——Fetch.get()
,用于调用 Fetch
的静态方法 get
。
先从 Fetch
的静态方法 get
入手,我们可以看到 get
方法内只有一行代码,里面的 then
暴露了“请求”是一个 Promise
的实例。
可以发现,“请求”接收到 resolved
信号时,需要执行 Fetch
的静态方法 检查返值
。
在检查反值中,程序系那个会判定“请求”resolve
时带上的参数。如果里面的参数不符合规定,则重新进行一次 Fetch.get()
。
锁定毒瘤
1 | class Fetch{ |
大哥的代码有毒,问题发生在 request().then()
上。
大哥的做法是 request().then(this.check)
。
虽然 check
方法还是可以执行,但是它只能执行一次。因为 Promise
的 then
内的作用域默认是全局 (global/windows
),而且在严格模式下是 undefined
,因此,this
指向(call
)的不是 Fetch
。所以在执行 this.check
函数时,check
内的 this
并不是 Fetch
对象,this.get()
取出来的是 undefined
,故 this.get();
是无法执行的,达不到大哥的需求。
动手修改
既然 this.check
它 call
的不是 Fetch
本身,那么我们可以用 .call
、.apply
、.bind
等可以调整函数的 this
的方式实现作用域的传递。
.call
我们知道,call()
方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。
1 | request() |
.apply
类似于 .call
,只是它传递参数值靠数组。
1 | request() |
.bind
bind()
方法会创建一个新函数。
当这个新函数被调用时,bind()的第一个参数将作为它运行时的 this, 之后的一序列参数将会在传递的实参前传入作为它的参数。
1 | request() |
不用 this
不用 this
就相当于直接指向 Fetch
本身。
1 | static check(value) { |
但是这样的做法,不是很好,可维护性比较差。
修改后的代码
最后,我们选择了最简洁的 .call
来实现这个需求。
1 | function request() { |
除非注明,麦麦小家文章均为原创,转载请以链接形式标明本文地址。