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

ES6+类语法扩展Function调用报错,如何实现自定义调用行为?

扩展Function类实现自定义调用行为的问题解决

问题原因

直接调用dict('one')时,函数内部的this遵循普通函数调用的绑定规则:非严格模式下指向全局对象,严格模式下指向undefined,并非你的SetOnceDict实例,因此找不到get方法报错。而dict.bind(dict)('one')能运行,是因为bind强制把函数内部的this绑定到了实例本身。

解决方案

方法一:绑定this并修正原型链

通过bind将函数的this绑定到实例,同时修正原型链确保继承类的方法:

class SetOnceDict extends Function {
  constructor() {
    super('key', 'return this.get(key);');
    const boundFn = this.bind(this);
    Object.setPrototypeOf(boundFn, SetOnceDict.prototype);
    return boundFn;
  }
  items = {};
  add(key, value) {
    if (!this.items.hasOwnProperty(key)) {
      this.items[key] = value;
    } else {
      throw new Error(`Duplicate key ${key}`);
    }
  }
  get(key) {
    return this.items[key];
  }
}

方法二:使用Proxy拦截函数调用

通过Proxy拦截函数的apply操作,直接将调用逻辑映射到实例的get方法,彻底规避this绑定问题:

class SetOnceDict extends Function {
  constructor() {
    super();
    return new Proxy(this, {
      apply(target, _, args) {
        return target.get(args[0]);
      }
    });
  }
  items = {};
  add(key, value) {
    if (!this.items.hasOwnProperty(key)) {
      this.items[key] = value;
    } else {
      throw new Error(`Duplicate key ${key}`);
    }
  }
  get(key) {
    return this.items[key];
  }
}

验证效果

let dict = new SetOnceDict();
dict.add('one', 'foo');
dict.add('two', 'bar');

console.log(dict.items); // 输出:{ one: 'foo', two: 'bar' }
console.log(dict('one')); // 输出:foo

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 11:30:59