【问题标题】:call method against every item in array对数组中的每个项目调用方法
【发布时间】:2014-01-22 16:05:41
【问题描述】:

想象一下我有这种类型:

function Greeter(greeting) {
     this.greeting = greeting;
}
Greeter.prototype.say = function(audience) { 
    audience = audience || "world";
    console.log(this.gretting, audience);
};

还有一个像这样的数组:

var greeters = [new Greeter("hello"), new Greeter("bonjour")];

有没有办法做这样的事情:

greeters.onEach("say", "people");
// outputs:
// hello people
// bonjour people

当然该方法是虚构的,但感觉应该有一些聪明的方法来做到这一点,而无需在 Array 原型上定义新方法,也许通过在 forEach/map/ 上使用 call/apply还有什么?

如果您有兴趣,这里是上述onEach 方法的简单实现:

Array.prototype.onEach= function(func) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    this.forEach(function(item) { 
        item[func].apply(item, args); 
    });
};

【问题讨论】:

  • @SLaks 这只是 Array.prototype.forEach 的一个 shim - OP 想要在每个对象上调用特定 named 函数的东西,而不是单个提供的函数引用。
  • @Alnitak 完全正确!它没有按照我的要求做,我已经展示了如何使用 forEach 来实现它
  • @WickyNilliams FWIW,我想不出比你已经写的更简单的了,这有点整洁。但是为了安全起见,您应该在可用的情况下使用Object.defineProperty(Array.prototype, 'onEach', ...),这样新方法就不会显示为每个Array 对象的可枚举属性。
  • 您拥有的代码就是您想要的代码。您可能希望首先确保该函数是否存在,但除此之外,您已经有了答案。

标签: javascript arrays function foreach


【解决方案1】:

你可以试试这样的:

greeters.forEach(function(greeter){
   greeter.say('people');
});

【讨论】:

  • 虽然这并不能严格回答 OP 的问题,但对于仅使用 forEach 这样的简单方法而不是创建新的辅助函数,还是有话要说的。
【解决方案2】:

经过一番思考,我认为实现这一目标的最佳方法是使用辅助函数。这样可以避免污染 Array 原型,并且仍然为解决这个问题提供了一种简洁的方法。它与我上面的onEach 方法非常相似,但使用闭包来创建可用作迭代器的函数。

function func(name) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function(obj) {
    return obj[name] && obj[name].apply(obj, args);
  }
}

然后可以像这样对上面的数组使用它:

greeters.forEach(func("say")); // call function "say" on each object
greeters.map(func("say", "people")); // ["hello people", "bonjour people"]

我怀疑这也将被视为解决问题的“更实用”的方法。在大型代码库中,这可能会节省大量样板代码。

【讨论】:

    猜你喜欢
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    相关资源
    最近更新 更多