You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法用filter移除数组中的绑定类方法?

问题原因与解决方案

根本原因不是作用域问题,而是**bind()方法的特性**:每次调用Function.prototype.bind()都会返回一个全新的函数实例——哪怕你绑定的是同一个原函数和同一个this上下文,两次bind的结果也不是同一个引用。

你代码里的问题:

  • 推送到数组的是第一次bind生成的函数A
  • 过滤时用的是第二次bind生成的函数B
  • A和B是两个不同的对象,全等判断f !== B永远为true,所以原函数A不会被过滤掉

解决方法

1. 提前保存绑定后的函数引用(推荐)

把绑定后的函数存为实例属性,复用这个引用做添加和移除操作:

let array: any[] = [];
class Test {
    private boundTestMethod: () => void;
    constructor() {
        // 只绑定一次,保存引用
        this.boundTestMethod = this.testMethod.bind(this);
        array.push(this.boundTestMethod);
        
        console.log('xxx', array); // [ [Function: bound ] ]
        
        // 用保存的引用做过滤判断
        array = array.filter(f => f !== this.boundTestMethod);
        
        console.log('xxx', array); // []
    }
    public testMethod(): void {
        return undefined;
    }
}

2. 使用箭头函数替代bind(类场景下更简洁)

在类中用箭头函数定义方法,箭头函数会自动捕获当前实例的this上下文,且整个实例生命周期内是同一个函数引用:

let array: any[] = [];
class Test {
    // 直接用箭头函数定义,自动绑定this
    public testMethod = (): void => {
        return undefined;
    }
    
    constructor() {
        array.push(this.testMethod);
        
        console.log('xxx', array); // [ [Function (anonymous)] ]
        
        array = array.filter(f => f !== this.testMethod);
        
        console.log('xxx', array); // []
    }
}

3. 特殊场景下的备选方案(不推荐)

如果无法提前保存引用,可以通过函数的name属性(绑定后的函数name为bound testMethod)或者自定义标识来匹配,但这种方法风险高——如果数组中有多个来自同一个原函数的绑定实例,会误删所有匹配项:

// 仅作演示,不推荐在生产环境使用
array = array.filter(f => f.name !== 'bound testMethod');

内容的提问来源于stack exchange,提问作者Kris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:12:23