2016-06-22 5 views
0

Привет, вот какой-то код из w3-школ, использующих метод уменьшения массива. Я пытаюсь научиться использовать это, однако я немного запутался в том, почему этот код работает. Причина в том, что numbers.reduce(getSum) doesent принимает параметры в функции getSum. Как наш код даже знает, сколько вещей внутри массива и как их суммировать, если мы даже не даем параметры функции getSum. В w3schools говорится: array.reduce(function(total,currentValue,currentIndex,arr),initialValue), а также говорит, что требуются total и currentValue. Но у нас их даже нет? у нас просто есть наша функция! Помогите пожалуйста.reduce метод для массивов

<!DOCTYPE html> 
<html> 
<body> 

<p>Click the button to get the sum of the numbers in the array.</p> 
<button onclick="myFunction()">Try it</button> 

<p>Sum of numbers in array: <span id="demo"></span></p> 

<script> 
var numbers = [65, 44, 12, 4]; 

function getSum(total, num) { 
    return total + num; 
} 
function myFunction(item) { 
    document.getElementById("demo").innerHTML = numbers.reduce(getSum); 
} 
</script> 

</body> 
</html> 

Heres другой пример .. не уверен, что разница

var numbers = [15.5, 2.3, 1.1, 4.7]; 

function getSum(total, num) { 
    return total + Math.round(num); 
} 
function myFunction(item) { 
    document.getElementById("demo").innerHTML = numbers.reduce(getSum,0); 
} 
+0

Разница в начальной величины: 'undefined' vs' 0'. с элементом 'undefined' first array будет использоваться вначале. Кроме того, второй округляет все числа до целых чисел. –

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce может объяснить это немного лучше, но в основном его можно записать как 'numbers.reduce (function (total, num) {return total + num;}); 'если' getSum' были заменены анонимной функцией. Остальное может быть лучше объяснено ссылкой. –

ответ

1

Синтаксис функции уменьшения является arr.reduce(callback[, initialValue]).

Это означает, что getSum называется обратным вызовом .

Что такое обратный вызов? Проще говоря, это ссылка на функцию, которая будет вызываться во второй момент.

Простой пример (но веб-полно руководства по обратному вызову):

function print(value) { 
    console.log(value) 
} 

function callCallback(callback) { 
    callback('Hello world!'); 
} 

callCallback(print); 

Как вы можете видеть печати является функцией, и ссылка на него передаются в качестве аргумента callCallback(). Затем функция вызывается внутри callCallback().

Давайте вернемся к вашему вопросу:

reduce() требует ссылки на функцию в качестве первого аргумента.

сокращение - это функция, и внутри она будет делать некоторые вещи (чтобы увидеть возможную реализацию, read here).

Где-то reduce() перезвонит функцию, которую вы передали в качестве аргумента, передав правильные параметры.

Мы уменьшить, что-то вроде этого:

reduce(callback) { 
    callback(previousValue, currentValue); 
} 

Таким образом, для каждого значения в массиве функция, которую вы прошли в качестве аргумента будет называться, и его аргументы будут заполнены previousValue и currentValue

Конечно, reduce() определенно длиннее, но в конце он берет вещь из массива, делает некоторую магию и переходит к функции, которую вы передали в качестве аргумента обратного вызова.

+0

Im вид путать.Как наша программа знает, как получить первое, второе и третье значение нашего массива? функция getsum может их добавить, но как мы их получаем? –

+0

@cresjoy Я обновил ответ. – rpadovani

+0

Значит, в принципе reduce() имеет встроенный способ прохождения через каждый элемент массива? –

1

В функции getSum, у вас есть два параметра, total и num Те, которые эквивалентны total и currentValue, соответственно, в вашем примере W3 Schools. В javascript ваша функция не должна иметь одинаковые имена переменных в функции. Для функции, которую вы передаете до reduce, требуются два аргумента, а первый будет использоваться как «общее количество», а второе - «текущее значение».

Что касается вопроса, как он знает, сколько значений находится внутри массива, посмотрите на полиполку, предоставленную MDN.Это дает некоторое представление о том, как можно реализовать функцию reduce для массива и знать, как долго будет массив.

+0

«Для функции требуется два аргумента вы проходите, чтобы уменьшить », это то, что мне действительно нужно, теперь мне просто нужно понять, как он знает, какие значения находятся в массиве. –

+0

@cresjoy Хорошо, поэтому он реализован как функция в прототипе Array. Основная идея заключается в том, что функция вызовет функцию обратного вызова для значения _every_ в массиве. По сути, это значение var; для {var i = 0; i pantalohnes

+0

oh. так что встроено в себя? –

1

массив.редукция (обратный вызов [, initialValue]).

Callback = функция, выполняемая для каждого значения массива, имеющая 4 аргумента.

1) previousValue = значение, возвращаемое в предыдущем обратном вызове ИЛИ значение, указанное с уменьшением.

2) currentValue = значение от текущего элемента массива.

3) currentIndex = индекс текущего элемента в массиве.

4) массив = массив, что она вызывается на

InitialValue не является обязательным, и дает наше предыдущее значение начальное значение в первом обратном вызове.

ТАК, на самом деле у вас есть аргументы. начальное значение (являющееся результатом предыдущего обратного вызова), фактическое число, индекс номера и массив чисел.

EDIT: Если вы не указали начальное значение, ваше предыдущее значение будет первым элементом массива, а ваше текущее значение - вторым.

EDIT 2: Ваше предыдущее значение в вашем первом прогоне будет 65, а ваше текущее значение будет 44. Они складываются, дают результат, который составляет 109, и дают это как результат. Функция вызывается до тех пор, пока вы не закончите свой массив. Таким образом, это означает, что возвращаемое значение вашего первого обратного вызова (109) будет предыдущим значением вашего второго обратного вызова. Снова он добавит предыдущий (109) и текущий, являющийся следующим (третьим) элементом в вашем массиве. Они добавляют их (109 + 12) и возвращают значение для следующего обратного вызова и т. Д. До тех пор, пока вы не пройдете весь массив. В конце он просто возвращает вам итог.

+0

Так как у нас есть 4 параметра, и (getsum) предоставляет 2, если мы делаем (getsum, 0), это только текущий индекс? IE, в чем разница между выполнением (getsum) vs (getsum, 0) –

+0

@cresjoy no, делая (getsum, 0), вы предоставляете функцию сокращения, это второй параметр, который является значением intial. Помните, что функция подобна this array.reduce (callback, initValue). значение init является необязательным.callback - это ваша фактическая функция getum, в этой функции вы ДОЛЖНЫ иметь текущее значение. – TanguyB

+0

@cresjoy Я отредактировал свой ответ, посмотрите на EDIT 2, вы должны понять, как работает эта функция. – TanguyB

0

Вы должны различать вызов функции и определение функции.

определение функции

function test() {} 

вызов функции

test(); 

пропускание функции требует определений функции не призванию, следовательно, вы можете передать ссылку (переменными определяющей функция) или само определение функции ,

numbers.reduce(functionVariableReference); // pass function definition 
numbers.reduce(function() {}) //anonymous function definition 

Array.reduce требует обратного вызова для выполнения на каждом элементе, этот обратный вызов передается следующие параметры при вызове, total,currentValue,currentIndex,arr

Другой пример:

function test(nOne, nTwo) {console.log(nOne + nTwo);} 
function passTwoAndThree(callback) {callback(2,3)}; 
passTwoAndThree(test) // will log 5; 
Смежные вопросы