【问题标题】:forEach() and Apply() methods for two dimensional array in JavaScriptJavaScript 中二维数组的 forEach() 和 Apply() 方法
【发布时间】:2016-04-17 07:08:38
【问题描述】:

我有一个数组,它的元素也是数组,每个数组包含三个元素。我想使用forEach() 方法为我的主数组的每个元素调用function calcMe(a,b,c){...},但我真的很困惑,不知道如何让它工作。

arr = [[1,5,4], [8,5,4], [3,4,5], [1,2,3]]
function calcMe(a,b,c){...}
arr.forEach(calcMe.Apply(-----, -----));

如何使用 Apply() 将每个内部数组的元素作为参数传递给我的函数?

【问题讨论】:

  • 请添加一些例子,这应该如何工作。
  • 并且不能通过数组和地址abc作为function calcMe(arr) { a = arr[0], b = arr[1]等?
  • 函数 calcMe(a,b,c) 应采用 1,5,4 然后 8,5,4 等作为参数

标签: javascript arrays multidimensional-array foreach


【解决方案1】:

apply 立即调用一个函数,所以你不能直接使用它,因为forEach 需要一个函数引用。但是,您可以在 apply 上使用 bind 来实现您想要的:

arr.forEach(Function.apply.bind(calcMe, void 0));

第二个参数将是this 值。您可以提供任何值而不是 void 0

var arr = [[1,5,4],[8,5,4],[3,4,5],[1,2,3]];
function calcMe(a,b,c){
  document.querySelector('pre').textContent += [a,b,c] + '\n';
}
arr.forEach(Function.apply.bind(calcMe, void 0));
<pre></pre>

【讨论】:

  • 我从没听说过Function.applyFunction.call,只有prototype versions
  • @JuanMendes 由于Function 是一个函数,它继承自Function.prototype。所以Function.applyFunction.prototype.apply的快捷方式。
  • 所以澄清一下,Function.apply.bind(calcMe, void 0)function() {calcMe.apply(null, arguments)}calcMe.apply.bind(calcMe) 是一样的?
  • Function.apply.bind(calcMe, void 0)calcMe.apply.bind(calcMe, void 0) 相同,因为Function.apply === calcMe.apply。并且和function(subArr) {calcMe.apply(void 0, subArr)}几乎一样,不同的是前者将额外的参数传递给apply,这些参数被忽略了。
  • @jacqui_g 基本上你可以选择是否要bind apply 或将其包装在函数表达式中。不能直接拨打apply
【解决方案2】:

首先,calcMe 似乎没有返回函数,因此您无法将其返回值传递给forEach

我猜你想要类似的东西

var arr = [
  [1, 5, 4],
  [8, 5, 4],
  [3, 4, 5],
  [1, 2, 3]
]

function calcMe(a, b, c) {
  var pre = document.getElementById('pre')
  pre.innerHTML += 'calcMe arguments: ' +  a +","+ b +","+ c  + "<br/>";
}

arr.forEach(function(el, index) {
  // Could also use `arr[index]` instead of el
  calcMe.apply(this, el);
});
&lt;pre id='pre'&gt;&lt;/pre&gt;

对于更高级的版本,you can bind Function.prototype.apply 来模拟我在上面所做的创建函数。

【讨论】:

  • 但是arr[index] 正好是el
  • 您在 forEach 回调中使用索引是否比 el(元素引用)有什么特殊原因?
  • @Mic 无特殊原因,澄清答案
  • 谢谢,效果很好。刚开始学javascript,不太懂forEach里面的函数,到底是怎么取主数组的索引的
  • @jacqui_g forEach 调用传递给它的函数,带有三个参数:第一个是数组中的当前元素,第二个是索引,第三个是被迭代的数组。跨度>
【解决方案3】:

您需要为.forEach 提供一个函数。该函数将在主数组的每个元素上运行。

根据calcMe 的作用,您可能需要在calcMe.apply 中为其提供正确的上下文。 .apply 的第一个参数是上下文(函数中的this 关键字)。我只是输入了null,但你可以传递适合你的。

var arr = [[1,5,4], [8,5,4], [3,4,5], [1,2,3]];
function calcMe(a,b,c){
    console.log(a, b, c);
}
arr.forEach(function (params) {
    calcMe.apply(null, params);
})

如果你愿意使用ES6,可以使用arrow functionsspread operator

arr.forEach(params => calcMe(...params));

【讨论】:

    【解决方案4】:

    如果您对ECMAScript 6 感兴趣,这里是最快最优雅的解决方案。

    'use strict';
    let arr = [
      [1, 5, 4],
      [8, 5, 4],
      [3, 4, 5],
      [1, 2, 3]
    ];
    
    function calcMe(a, b, c) {
      document.querySelector('p').innerHTML += `${a},${b},${c}<br>`;
    }
    
    for (let item of arr) {
      calcMe(...item);
    }
    
    // Or
    arr.forEach(item => calcMe(...item));
    &lt;p&gt;&lt;/p&gt;

    【讨论】:

      【解决方案5】:

      你可以提供一个 lambda 函数

      arr.forEach((u)=>{console.log(calcMe.apply(null, u))});
      

      如果您不需要访问对象上下文,将null 绑定到第一个参数应该没问题。否则,绑定你想要的对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-06
        • 2018-08-31
        • 2010-09-16
        相关资源
        最近更新 更多