首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重写_.invoke

重写_.invoke
EN

Stack Overflow用户
提问于 2020-12-08 15:23:54
回答 1查看 355关注 0票数 1

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

这是我的密码:

代码语言:javascript
运行
复制
_.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;
};

由于没有正确传递参数,它目前失败了。有人能给我任何建议或建议,为什么会发生这种情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-08 15:28:09

您传递的是arguments伪数组,而不是它的内容,并且传递的是整个过程,但是您可能不想传递方法名称的集合。

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

代码语言:javascript
运行
复制
_.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;
};

附带注意:您可能希望允许任何可迭代的,而不仅仅是一个数组,并且可以使用Object.values获取对象值的数组。

代码语言:javascript
运行
复制
_.invoke = function (collection, methodName, ...args) {
    const iterable = isIterable(collection) ? collection : Object.values(collection);
    const res = Array.from(iterable).map(entry => entry[methodName](...args));
    return res;
};

...where isIterable是:

代码语言:javascript
运行
复制
function isIterable(obj) {
    return obj && typeof obj[Symbol.iterator] === "function";
}

或者,如果执行数组的浅表副本会不必要地困扰您:

代码语言:javascript
运行
复制
_.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;
};

如果您需要在collection上重复执行这三步操作,您可以使用一个助手函数:

代码语言:javascript
运行
复制
function arrayForAny(x) {
    const array = Array.isArray(x) ? x :  isIterable(x) ? Array.from(x) : Object.values(x);
}

您还可以检查是否喜欢数组,并将它们传递到Array.from,而不是在它们上使用Object.values。但我已经爬过山顶了所以..。;-)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65201722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档