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() { |
除非注明,麦麦小家文章均为原创,转载请以链接形式标明本文地址。