Как работает стек вызова функций при рекурсии?

83
19 марта 2021, 08:30

Написал простую рекурсию (работает как задумано):

const arr = [1,2,3,10]; 
let result = 0; 
let i = 0; 
const sum = mas => { 
  if(i < mas.length){ 
    result += mas[i]; 
    i++; 
    return sum(mas); 
  } else { 
    return result; 
  } 
} 
console.log(sum(arr));

Начал играться. Первое что я сделал это убрал return из первого if и дописал console.log(result); после вызова самой себя:

const arr = [1,2,3,10]; 
let result = 0; 
let i = 0; 
const sum = mas => { 
  if(i < mas.length){ 
    result += mas[i]; 
    i++; 
    sum(mas); 
    console.log(result); 
  } else { 
    return result; 
  } 
} 
console.log(sum(arr));

Сначало результат меня удивил, но потом я понял, что сначало вызвалась 4 раза функция, которая посчитала сумму, и только потом отработал console.log(result); так же 4 раза. Но тут в конце я увидел undefined. Чуть поменяв код, я получил результат:

const arr = [1,2,3,10]; 
let result = 0; 
let i = 0; 
const sum = mas => { 
  if(i < mas.length){ 
    result += mas[i]; 
    i++; 
    sum(mas); 
    console.log(result); 
  } 
  return result; 
} 
console.log(sum(arr));

А теперь вопрос: почему в else return, именноreturn, возвращает undefined, так как если поставить перед ним console.log(result);, в консоле мы увидим корректный результат?

Answer 1

Рассмотрим второй пример, строку

console.log(sum(arr));

Что выдаст лог? Конечно, результат работы функции sum(arr)

А что делает функция sum(arr)

const sum = mas => {
    if(i < mas.length){      // <-- i == 0, проваливаемся в if
        result += mas[i];    // <-- прибавили к result i-ый элемент массива
        i++;                 // <-- увеличили i
        sum(mas);            // <-- запустили рекурсивно функцию
        console.log(result); // <-- залогировали result и...
                             // <-- ...ничего не вернули
    } else {
        return result;       // <-- это не выполнится, так как зашли в if
    }
}

В JavaScript функция всегда возвращает результат. Если не указать return функция вернет undefined.

Этот undefined и выводит console.log(sum(arr));

В третьем примере функция sum(arr) вернет результат

const sum = mas => {
    if(i < mas.length){
        result += mas[i];
        i++;
        sum(mas);
        console.log(result); // <-- выполнение функции не закончено
    }
    return result;           // <-- нужно еще выполнить эту строку, вернуть `result`
}
READ ALSO
Изменить атрибут src img

Изменить атрибут src img

На сайте имеется блок < div id='recentpostsae' > с последними публикациямиВ нем нужно изменить src img, с 's72-c' на 's150-c', в данный момент src имеет вид https://site

158
как сформировать многомерный массив из data данных

как сформировать многомерный массив из data данных

как сформировать многомерный массив как в var example обходя доступные данные вот в этом простом примере ?

66
Подключение к базе данных на C++

Подключение к базе данных на C++

Пытаюсь подключиться к базе данных SQL через плюсы

107