能否通过继承Function类实现指定JavaScript代码?若无有何替代方案?
关于继承Function类实现你的工具函数的问题
嘿,先直接给你结论:继承Function类是可行的,但完全没必要——而且你的原代码有个不小的坑,我来给你拆解清楚,再给你更优的原生JS实现方案。
先说说原代码的问题
你的原代码把_data挂在了Function.prototype上,这意味着所有JavaScript函数都会共享这个Map——比如随便定义一个function foo() {},foo._data也会指向同一个Map,很容易造成误操作或者数据污染,这绝对是要避免的。
能不能继承Function类?
理论上可以,比如你可以这么写:
class Temp extends Function { static _data = new Map(); constructor() { // 调用Function构造函数创建一个可调用的函数实例 super('key', 'return Temp._data.get(key)'); } static remove(id) { this._data.delete(id); } static reset() { this._data.clear(); } static store(key, val) { this._data.set(key, val); } }
但问题来了:你需要调用new Temp()才能得到一个可调用的函数实例,而你的原需求是直接调用TEMP(key)就能获取值,不是创建实例。如果想让Temp本身(而不是它的实例)可调用,你还得额外修改构造函数的行为,这会让代码变得复杂且不符合直觉,完全是舍近求远。
更优的原生JS实现方案
其实你的需求非常适合用函数对象直接扩展的方式实现——既保留了直接调用的能力,又能添加工具方法,还不会污染原型链。代码如下:
// 核心:创建一个可直接调用的函数,内部访问自身的_data属性 const Temp = function(key) { return Temp._data.get(key); }; // 给函数对象添加专属的Map和方法,完全独立,不影响其他函数 Temp._data = new Map(); Temp.remove = function(id) { this._data.delete(id); }; Temp.reset = function() { this._data.clear(); }; Temp.store = function(key, val) { this._data.set(key, val); };
如果你喜欢箭头函数的简洁写法,也可以这么写:
const Temp = (key) => Temp._data.get(key); Temp._data = new Map(); Temp.remove = (id) => Temp._data.delete(id); Temp.reset = () => Temp._data.clear(); Temp.store = (key, val) => Temp._data.set(key, val);
这个方案的优势:
- 完全符合需求:直接调用
Temp('myKey')就能获取值,调用Temp.store('myKey', 'value')就能存数据,和原代码用法一致。 - 无原型污染:
_data是Temp函数自身的属性,不会影响任何其他函数。 - 简洁直观:代码逻辑清晰,不需要复杂的类继承或原型操作。
额外小优化
如果你想避免外部直接修改_data,可以用闭包封装起来,让数据更安全:
const Temp = (() => { const _data = new Map(); const tempFn = (key) => _data.get(key); tempFn.remove = (id) => _data.delete(id); tempFn.reset = () => _data.clear(); tempFn.store = (key, val) => _data.set(key, val); return tempFn; })();
这样外部无法直接访问_data,只能通过提供的方法操作,进一步提升了数据的安全性。
内容的提问来源于stack exchange,提问作者Richard Clink
相关产品推荐
相关产品推荐

