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
相关产品推荐
相关产品推荐

