[原创教程]JS/TS如何优雅地向回调函数传递this对象

1、问题呈现

笔者是前端小萌新,最近在编写前端代码的时候遇到了这样一个需求:使用第三方Vue组件「Draggable_Plus」的回调函数更改「自定义对象」的成员变量。

2、问题背景

由于给定回调函数只有一个evt变量,要使回调函数能够更改自定义变量,只能在定义函数的作用域内创建对象并将对象写在回调函数的定义域内。但是这样的话,会使得代码结构散乱:我有多个自定义对象,每个对象需要相似的回调函数来改变成员变量,而且每个组件都需要绑定这些回调函数。

在Vue中一个常规的方案是使用组合API函数,即hook函数,将改变对象成员变量的逻辑封装进函数以便实现复用。但是这样我觉得会使业务代码松散,每一种对象的每一个逻辑都要封装为hook函数,会出现许多凌乱的hook函数

3、问题分析

于是笔者便尝试将回调函数封装为成员函数,通过调用this指针来更改成员变量。但是却遇到了问题,由于回调函数运行的上下文不在对象内,函数中的this指针为null。

想要将回调函数封装为成员函数,就需要向回调函数传递this指针。通过互联网,我得知函数都有call方法可以指定this的指向。

call方法

4、问题解决

于是我在每一个对象内部封装了callback方法,调用真正的回调函数的call()方法,将其作为闭包使用,以便能够获取this指针。

class Area{
    callback(func: Function) {
        return (evt:any) => {func.call(this,evt)};
    }

    // 真正的回调函数
    update_add(evt: any): void {
        console.log(this);
    }
}

在传递回调函数时只需调用callback函数。

let area = new Area();
on-add = area.callback(area.update_add)

成功打印出了this对象!

1 个赞