Javascript 重写.调用

Javascript 重写.调用,javascript,underscore.js,Javascript,Underscore.js,我正试图从头重写u.invoke函数,但只能使它工作一半。我的函数应该接受一个集合、一个methodName和可选的附加参数,并返回一个数组,其中包含对集合中的每个值调用methodName指示的方法的结果。传递给invoke的任何额外参数都将转发给方法调用 这是我的密码: _.invoke = function (collection, methodName) { let res = []; if (Array.isArray(collection)) { for (let i

我正试图从头重写u.invoke函数,但只能使它工作一半。我的函数应该接受一个集合、一个methodName和可选的附加参数,并返回一个数组,其中包含对集合中的每个值调用methodName指示的方法的结果。传递给invoke的任何额外参数都将转发给方法调用

这是我的密码:

_.invoke = function (collection, methodName) {
  let res = [];
  if (Array.isArray(collection)) {
    for (let i = 0; i < collection.length; i++) {
      res.push(collection[i][methodName](arguments));
    }
  } else {
    for (const [key, value] of Object.entries(collection)) {
      res.push(value[methodName](arguments));
    }
  }
  return res;
};
\uuu.invoke=函数(集合,方法名){
设res=[];
if(数组.isArray(集合)){
for(设i=0;i

由于未正确传递参数,它当前失败。有人能给我一些建议吗?

你传递的是
参数
伪数组,而不是它的内容,你传递的是整个数组,但你可能不想传递方法名的集合

相反,在函数签名上使用rest参数,然后在调用方法时将其展开:

_.invoke = function (collection, methodName, ...args) {
//                                         ^^^^^^^^^−−−−−−− rest param
  let res = [];
  if (Array.isArray(collection)) {
    for (let i = 0; i < collection.length; i++) {
      res.push(collection[i][methodName](...args));
//                                       ^^^−−−−−−−−−−−−−−− spread notation
    }
  } else {
    for (const [key, value] of Object.entries(collection)) {
      res.push(value[methodName](...args));
//                               ^^^−−−−−−−−−−−−−−−−−−−−−−− spread notation
    }
  }
  return res;
};
…其中,
isIterable
是:

function isIterable(obj) {
    return obj && typeof obj[Symbol.iterator] === "function";
}
或者,如果执行阵列的浅拷贝不必要地困扰您:

_.invoke = function (collection, methodName, ...args) {
    const array = Array.isArray(collection)
        ? collection
        :  isIterable(collection) ? Array.from(collection) : Object.values(collection);
    const res = array.map(entry => entry[methodName](...args));
    return res;
};
如果您需要重复执行
收集
的三个步骤,您可以使用一个helper函数:

function arrayForAny(x) {
    const array = Array.isArray(x) ? x :  isIterable(x) ? Array.from(x) : Object.values(x);
}

您还可以检查数组类并将它们传递到
array.from
中,而不是对它们使用
Object.values
。但我已经超过了这里的最高点,所以…;-)

还值得注意的是,
if
是不需要的-对于这两种情况,它都可以是
for(Object.entries(collection))的const[key,value]{res.push(value[methodName](…args));}
。甚至使用
Object.values
@VLAZ-Heh,类似的想法。我想建议将它扩展到任何iterable,并将这两个分支统一起来。是的,事实上,我开始编写基本上与您相同的内容,并建议删除
if
。由于您在我之前发布了帖子,我认为与其得到(几乎)相同的答案,不如只发表评论真的很有帮助,非常感谢你的帮助!
function arrayForAny(x) {
    const array = Array.isArray(x) ? x :  isIterable(x) ? Array.from(x) : Object.values(x);
}