让我向您展示我要完成的事情的一个例子:
说我想调用函数子函数的子函数的子函数(依此类推,比如说50多个子函数),例如:
foo(arg).bar(other).foobar(int, str).execute(str)
并想象有50个以上的子函数,因此键入每个子调用是不切实际的。
SO:如何基于这样的数组编写函数以调用子函数的子函数,等等...(基于数组的长度)?示例):
[["foo",["asdf"]],["bar",["other"]],["foobar",[123,"hi"]],["execute",["today"]]]
要清楚,我不是简单地尝试使用相应的参数分别调用数组中的每个函数,我可以轻松地做到这一点:
arr.forEach(x=>functionDictionary(x[0])(...x[1])
我想简单地得到这个:
foo(arg).bar(other).foobar(int, str).execute(str)
从这里:
[["foo",["asdf"]],["bar",["other"]],["foobar",[123,"hi"]],["execute",["today"]]]
答案 0 :(得分:5)
使用reduce
遍历数组并调用每个函数,并将返回值作为累加器传递给下一次迭代:
// using just a single object to make the indentation much more readable:
const obj = {
foo(arg) {
console.log('foo called with ' + arg);
return this;
},
bar(arg2) {
console.log('bar called with ' + arg2);
return this;
},
foobar(argA, argB) {
console.log('foobar called with ' + argA + ' ' + argB);
return this;
},
execute(arg5) {
console.log('execute called with ' + arg5);
return this;
}
};
const arr = [
["foo", ["asdf"]],
["bar", ["other"]],
["foobar", [123, "hi"]],
["execute", ["today"]]
];
arr.reduce((a, [key, args]) => a[key](...args), obj);
请注意,此处我将obj
作为初始值传递,以便第一个["foo"]
可以访问obj.foo
,而不是使用eval
来引用变量在名为foo
的当前范围内。
答案 1 :(得分:1)
尝试
arr.forEach( x => r=r[x[0]](...x[1]) );
其中,arr包含具有函数名称-参数的数组,r包含具有函数的对象(并在结果末尾)。
const o = {
fun1(arg) { console.log('fun1 ' + arg); return this;},
fun2(arg1,arg2) { console.log('fun2 ' + arg1 +'-'+ arg2); return this; },
fun3(arg) { console.log('fun3 ' + arg); return this;},
};
const arr = [
["fun1", ["abc"]],
["fun2", [123, "def"]],
["fun3", ["ghi"]]
];
let r=o; // result
arr.forEach( x => r=r[x[0]](...x[1]) );
如果您要在函数不返回下一个对象时中断调用链,请使用
arr.forEach( x => r= r ? r[x[0]](...x[1]) : 0 );
const o = {
fun1(arg) { console.log('fun1 ' + arg); return this;},
fun2(arg1,arg2) { console.log('fun2 ' + arg1 +'-'+ arg2); },
fun3(arg) { console.log('fun3 ' + arg); return this;},
};
const arr = [
["fun1", ["abc"]],
["fun2", [123, "def"]],
["fun3", ["ghi"]]
];
let r=o; // result
arr.forEach( x => r= r ? r[x[0]](...x[1]) : 0 );