动态调用方法Java脚本

时间:2018-08-10 21:30:13

标签: javascript arrays object methods

我创建了一个名为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'] }

1 个答案:

答案 0 :(得分:1)

您在这里遇到了一些问题。

第一个call的第一个参数为this,随后的参数为实际参数。由于您未在函数中使用this,因此只需传递nullitem2.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
    }, {}) 
}