【问题标题】:Invoking a Method dynamically | Javascript动态调用方法 | Javascript
【发布时间】:2023-03-12 04:45:02
【问题描述】:
我创建了一个名为 multiMap 的函数,它接受两个数组作为参数并将它们映射到对象中的键值对。在某些情况下,第二个值数组可能是函数,它将成为我新创建的对象中的方法。
我希望使用作为字符串参数传入的相应键来调用方法值。我正在尝试使用 obj[item1].call(item1);但我似乎无法以这种方式正确调用该函数。感谢任何帮助。
let multiMap = (arr1, arr2) => {
const obj = {};
for(let item1 of arr1) {
for(let i = 0; i < arr2.length; i++) {
let item2 = arr2[i]
obj[item1] = item2;
obj[item1].call(item1);
}
}
return obj;
}
function uppercaser(str) { return str.toUpperCase(); }
function capitalize(str) { return str[0].toUpperCase() + str.slice(1).toLowerCase(); }
function repeater(str) { return str + str; }
var items = ['catfood', 'glue', 'beer'];
var functions = [uppercaser, capitalize, repeater];
console.log(multiMap(items, functions)); // should log: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] }
【问题讨论】:
标签:
javascript
arrays
object
methods
【解决方案1】:
这里有一些问题。
首先call 将this 作为它的第一个参数,然后是实际参数。由于您没有在函数中使用this,因此您只需传递null:item2.call(null, item1)。
此外,由于您需要一个值数组,因此有时您需要创建该数组。我会在第一个 for 之后推荐:
let multiMap = (arr1, arr2) => {
const obj = {};
for(let item1 of arr1) {
obj[item1] = [] // make the array
for(let i = 0; i < arr2.length; i++) {
let item2 = arr2[i]
obj[item1].push(item2.call(null, item1)); // now just push into the array
}
}
return obj;
}
function uppercaser(str) { return str.toUpperCase(); }
function capitalize(str) { return str[0].toUpperCase() + str.slice(1).toLowerCase(); }
function repeater(str) { return str + str; }
var items = ['catfood', 'glue', 'beer'];
var functions = [uppercaser, capitalize, repeater];
console.log(multiMap(items, functions));
另外由于你没有使用call 设置this 的能力,你可以直接调用函数:
obj[item1].push(item2(item1));
将所有这些与map 放在一起,您可以将函数简化为:
let multiMap = (arr1, arr2) => {
const obj = {};
for(let item1 of arr1) {
obj[item1] = arr2.map(fn => fn(item1))
}
return obj;
}
甚至:
let multiMap = (arr1, arr2) => {
return arr1.reduce((obj, item) => {
obj[item] = arr2.map(fn => fn(item))
return obj
}, {})
}