在 Array.prototype 中为 "for each" 循环传递参数的语法是什么?

What is the syntax for passing in an argument for a "for each" loop in Array.prototype?

如果我有这样的代码:

QB_list.x.forEach(pushElementsQB)

function pushElementsQB(element, index, array)
{
    rows.push([element, QB_list.y[index], "QB: " + QB_list.text[index], null, null, null, null]);
}

有没有办法在我的回调中指定行变量?我是 javascript 的新手,这次 spec 对我不起作用 :/

正如@Grundy 所提到的,一种方法是在函数内部设置 bind 的值:

QB_list.x.forEach(pushElementsQB.bind(rows))

function pushElementsQB(element, index, array) // here this will be rows
{
    this.push([element, QB_list.y[index], "QB: " + QB_list.text[index], null, null, null, null]);
}

这与设置 forEach 的第二个参数相同:

QB_list.x.forEach(pushElementsQB, rows)

另一种方法也是将行添加为额外参数:

QB_list.x.forEach(pushElementsQB.bind(QB_list.x.forEach.args,rows))

然后使用:

function pushElementsQB(rows, element, index, array) // be careful, rows is the first parameter now
{
    rows.push([element, QB_list.y[index], "QB: " + QB_list.text[index], null, null, null, null]);
}

为什么不直接使用 map

var rows = QB_list.x.map(pushElementsQB);

function pushElementsQB(element, index, array)
{
    return [element, QB_list.y[index], "QB: " + QB_list.text[index], null, null, null, null];
}

map 本质上是 forEach,returns 是 Array

对于这个用例,@Mathletics 对 Map 的回答是最好的,但要回答这个问题,并扩展@juvian 和@Grundy 的回答。您可以使用 Bind 绑定上下文(this 关键字)。但是,这是危险的,因为您使该函数采用该上下文,并且这些参数 永远 ,并且在所有其他用法中直到未绑定。

您可以按如下方式以更简单、更安全、更符合预期的方式执行此操作。

Array.forEach的第二个参数是thisArg。给这些行,它在不使用绑定的情况下完成相同的工作。

var rows = []; // Declare rows variable
QB_list.x.forEach(pushElementsQB, rows) // Pass it in for the callbacks context

function pushElementsQB(element, index, array) {
     this.push([element, QB_list.y[index], "QB: " + QB_list.text[index],  null, null, null, null]);
}

如果你真的想把变量强加到参数中,你可以这样做:

var rows = []; // Declare rows variable
QB_list.x.forEach(function() { 
    pushElementsQB.apply(
        QB_list.x, // Set the function to be called with list as context (`this`)
        arguments.concat([rows]) // Grab the arguments to this function, append rows, set the function to be called with that appended list
    ) 
})

function pushElementsQB(element, index, array, rows) {
    // Rows is appended to the end of the arguments list, so, maps to 'rows' argument here
    rows.push([element, QB_list.y[index], "QB: " + QB_list.text[index],  null, null, null, null]);
}

map,按照 Mathletics 的建议是一个不错的选择。使用它的另一个很好的理由是您可以传入一个初始参数,该参数在回调中充当 this 。例如,如果 rows 已经被声明并且你想向它推送更多数据,你可以执行如下操作:

var data = { x: [1, 2, 3, 4] };
var rows = [2];

// pass in `rows` as the initial argument
data.x.map(pushElementsQB, rows);

function pushElementsQB(el) {

  // `this` is `rows`, and `map` appends the elements
  // from data.x to it.
  return this.push(el);
}

console.log(rows); // [2, 1, 2, 3, 4]

非常整洁。

DEMO