为了设置 Socket.IO 客户端,我有很多如下所示的方法:
myobject.prototype.A = function (callback) {
this.foo('a', null, callback);
}
myobject.prototype.B = function (bar, callback) {
this.foo('b', { bar }, callback);
}
myobject.prototype.C = function (baz, qux, callback) {
this.foo('c', { baz, qux }, callback);
}
this.foo
的内容并不重要,但它需要 3 个参数:一个字符串、一个根据调用方法参数构建的对象和一个回调方法。
我希望将这些方法设置在一个地方。我想要看起来像这样的东西:
// I'm not sure what form the args should take
const methods = {
A: { socketName: 'a', args: [ ] },
B: { socketName: 'b', args: [ 'bar' ] },
C: { socketName: 'c', args: [ 'baz', 'qux' ] }
};
for (let m in methods) {
const mData = methods[m];
this.prototype[m] = function (what_do_I_put_here_?, callback) {
// how do I form "otherArgs" ?
this.foo(mData.socketName, otherArgs, callback);
}
}
我想我必须考虑解构赋值,但我不确定在这种情况下如何使用它们。
最佳答案
您可以利用闭包和数组函数来做到这一点:
"use strict"
class Test {
createDynFoo(name, propertyNames = []) {
// return an arrow function (ensures that this is still the obj)
return (x, ...args) => {
let obj = null; // set obj to null as default
if (args.length > 0) {
// if we have additional aguments to x we create an obj
obj = {};
// map the additional arguments to the property names
propertyNames.forEach((value, idx) => {
obj[value] = args[idx]
})
}
// call the actual foo function
return this.foo(name, x, obj)
}
}
foo(name, x, obj) {
console.log(`${name} ${x}`)
console.dir(obj);
}
}
let test = new Test();
let tiggerForA = test.createDynFoo('a');
let tiggerForB = test.createDynFoo('b', ['y']);
let tiggerForC = test.createDynFoo('c', ['y', 'z']);
tiggerForA(1);
tiggerForB(1, 2);
tiggerForC(1, 2, 3);
如果您确实需要它作为成员函数,您可以这样做:
"use strict"
class Test {
constructor() {
this.A = this.createDynFoo('a');
this.B = this.createDynFoo('b', ['y']);
this.C = this.createDynFoo('c', ['y', 'z']);
}
createDynFoo(name, propertyNames = []) {
// return an arrow function (ensures that this is still the obj)
return (x, ...args) => {
let obj = null; // set obj to null as default
if (args.length > 0) {
// if we have additional aguments to x we create an obj
obj = {};
// map the additional arguments to the property names
propertyNames.forEach((value, idx) => {
obj[value] = args[idx]
})
}
// call the actual foo function
return this.foo(name, x, obj)
}
}
foo(name, x, obj) {
console.log(`${name} ${x}`)
console.dir(obj);
}
}
let test = new Test();
test.A(1);
test.B(1, 2);
test.C(1, 2, 3);
如果它只是关于成员函数,你可以像这样去掉箭头函数:
"use strict"
function createDynFunction(classObj, targetFunctionName, newFunctionName, name, propertyNames = []) {
// create a new function and assigned it to the prototype of the class
classObj.prototype[newFunctionName] = function(x, ...args) {
let obj = null; // set obj to null as default
if (args.length > 0) {
// if we have additional aguments to x we create an obj
obj = {};
// map the additional arguments to the property names
propertyNames.forEach((value, idx) => {
obj[value] = args[idx]
})
}
// call the actual foo function
return this[targetFunctionName](name, x, obj)
}
}
class Test {
foo(name, x, obj) {
console.log(`${name} ${x}`)
console.dir(obj);
}
}
createDynFunction(Test, 'foo', 'A', 'a');
createDynFunction(Test, 'foo', 'B', 'b', ['y']);
createDynFunction(Test, 'foo', 'C', 'c', ['y', 'z']);
let test = new Test();
test.A(1);
test.B(1, 2);
test.C(1, 2, 3);
由于我不知道确切的用例,因此很难想出完全符合需求的解决方案。但根据显示的代码,您应该了解如何实现这一点。
关于javascript - 如何动态创建一个方法,并将可变数量的参数存储在变量中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77352609/