如何在JavaScript中将对象像函数一样调用?
如何让JavaScript中的对象像函数一样被调用?
函数与普通对象的调用差异
函数可以通过括号直接调用:
const myFunc = function () { console.log('Function has been invoked'); } myFunc(); // 输出 "Function has been invoked"
但普通对象无法用这种方式调用:
const myObj = {}; myObj(); // TypeError: myObj is not a function
尝试让对象可调用的几种方法
直接设置[[Call]]内部方法
函数能被调用是因为拥有内部方法[[Call]],但直接给对象添加这个属性会报错:
const myObject = { [[Call]]: function() { console.log("My object was invoked!"); } }; // ReferenceError: Call is not defined
根据ECMAScript规范,开发者无法自行配置、访问或修改对象的[[Call]]内部属性。
使用Proxy的apply陷阱
Proxy的apply陷阱可捕获函数的[[Call]]操作,但代理普通对象时无法生效:
const callableObject = new Proxy({}, { apply: function() { console.log("Callable object was invoked!"); } }); callableObject(); // TypeError: callableObject is not a function
修改原型链结合Proxy
尝试将对象原型设为Function.prototype再用Proxy代理,结果依然报错:
const obj = {}; Object.setPrototypeOf(obj, Function.prototype) const callableObject = new Proxy(obj, { apply: function() { console.log("Callable object was invoked!"); } }); callableObject(); // TypeError: callableObject is not a function
可行方案
目前唯一可靠的方式是创建一个函数,同时将其当作对象使用——因为函数本身就是特殊的对象,既可以被调用,也能添加属性:
// 创建兼具对象特性的函数 const callableObj = function() { console.log("Callable object was invoked!"); }; // 给函数添加对象属性 callableObj.userInfo = { name: "grentank", role: "developer" }; // 调用函数 callableObj(); // 输出 "Callable object was invoked!" // 访问对象属性 console.log(callableObj.userInfo.name); // 输出 "grentank"
内容的提问来源于stack exchange,提问作者grentank
相关产品推荐
相关产品推荐

