通过实现call
或apply
方法或以其他方式,是否可以使对象可调用?例如:
var obj = {};
obj.call = function (context, arg1, arg2, ...) {
...
};
...
obj (a, b);
通过实现call
或apply
方法或以其他方式,是否可以使对象可调用?例如:
var obj = {};
obj.call = function (context, arg1, arg2, ...) {
...
};
...
obj (a, b);
function foo(){}
foo.myProperty = "whatever";
编辑:要将一个对象“制作”为可调用的,您仍然需要执行上述操作,但它可能看起来像:
// Augments func with object's properties
function makeCallable(object, func){
for(var prop in object){
if(object.hasOwnProperty(prop)){
func[prop] = object[prop];
}
}
}
那么你只需要使用"func"函数而不是对象。这个方法实际上只是在两个对象之间复制属性,但是...它可能会对你有所帮助。
obj[Symbol.invoke] = function(args) { };
。 - Nick SotirosObject.setPrototypeOf(func, object)
吗? - Rodrigo Rodriguesname
)发生冲突,则此操作将失败。例如:(function(){}).name='';
会导致以下错误:TypeError: Cannot assign to read only property 'name' of function 'function(){}'
。 - James WilkinsES6
现在有更好的解决方案。如果您以不同的方式创建对象(使用class
,extend
'Function'类型),则可以拥有可调用的实例。
另请参见:如何使用ES6类扩展函数?
extends
,所以您最好将其用于语言的解决方法,重用代码,您可能应该将其聚合在类内部,或者仅在域对象中进行自然连接。 - Azder继@Max的思路,但使用ES6扩展Object
来传递对象obj
的所有属性和原型到可调用的func
。
Object.assign(func, obj);
Object.setPrototypeOf(func, Object.getPrototypeOf(obj));
其他人已经提供了当前的答案(“否”)和一些解决方法。至于未来的一流支持,我曾向es-discuss邮件列表建议过这个问题。那时候这个想法没有得到很大的推进,但也许一些额外的兴趣会帮助再次推进这个想法。
“可调用对象”
我还没有看到提到这种类型的答案..但这就是我如何处理“可调用”对象:
<< 伪代码 >>
{...objectWithFunctionsInside}[keyString](optionalParams)
简短的示例定义了第一种、最简单和首选的方法,如果我只想要一个“可调用对象”,在我的定义中:
let obj = {
o:()=>{return("oranges")},
b:()=>{return("bananas")},
s:"something random here, doesn't have to be functions"
}
obj["o"]()
以下是一个短的示例,展示了在函数返回中运行无名对象,并带有参数(请注意,参数在第一个示例中也适用):
function autoRunMyObject(choice,param){
return{
o:(p)=>{return(p+"oranges")},
b:(p)=>{return(p+"bananas")},
}[choice](param)
}
autoRunMyObject("b","orange you glad I didn't say ")
就是这样了。 您甚至可以更加奇怪,使用匿名函数自动运行并立即生成输出... 没有任何原因,哈哈。 ... 按F12并将此代码复制到浏览器控制台中,然后按Enter,您将立即获得带有完整字符串的输出:
((autoparam="o")=>{return{
o:(p)=>p+"oranges",
b:(p)=>p+"bananas",
}[autoparam]("I guess this time it's ")})()
你甚至可以在最后一个括号中传入字符串"b",以获得与默认值"o"不同的输出结果。
此外,我的每个示例(除了伪代码第一个示例)都可以轻松地复制/粘贴到浏览器控制台中进行快速测试——这是一个很好的实验JS的地方。
总之——这就是我喜欢做“可调用对象”的方式。
它比
SWITCH(){CASE:BREAK;};
语句和
IF{}ELSE IF(){}ELSE IF(){};
链要好得多。