Если у меня есть такой код:

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 на этот раз у меня не работает: /

0
smuggledPancakes 16 Дек 2015 в 20:43

4 ответа

Лучший ответ

Как упомянул @Grundy, один из способов сделать это - установить с помощью bind значение this внутри функции:

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]);
}
1
juvian 16 Дек 2015 в 17:57

Почему бы просто не использовать 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, который возвращает Array.

3
Mathletics 16 Дек 2015 в 17:55

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]

Довольно аккуратно.

ДЕМО

1
Andy 16 Дек 2015 в 18:16

Для этого варианта использования @ Mathletics ответ Map был бы лучшим, но ответить на вопрос и расширить на @juvian и @ Grundy ответ. Вы можете связать контекст (ключевое слово this), используя Bind. Однако это ужасно, так как вы заставляете эту функцию принимать этот контекст и эти аргументы forever и во всех других случаях использования до тех пор, пока они не будут связаны.

Вы можете сделать это более простым, безопасным, а затем более ожидаемым способом следующим образом.

Второй параметр 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]);
}
1
Andy James 16 Дек 2015 в 18:11