Рекурсии сделаны правильно

Я пытаюсь написать функцию, которая должна возвращать список из 6 элементов. Он должен принимать пустой массив, «режим», который здесь должен быть «добавить», и третий параметр, который представляет собой номер, на который должен увеличиваться следующий элемент (по сравнению с предыдущим элементом). Например, возвращаемый массив может быть чем-то вроде

[4, 6, 8, 10, 12, 14]

http://jsbin.com/vuvunotifu/edit?js,console

Я тестировал это на JsBin, однако, похоже, в последнем блоке if есть переполнение стека (без каламбура). Не знаю почему. Кто-нибудь знает, как это решить?

  function getRandomInt(max){
  return Math.floor(Math.random() * Math.floor(max));
}


function getSequence(array, mode, differBy){
  if (mode === 'add'){
    if (array.length >= 6){
      return array;
    }
    if (array.length === 0){
      array.push(getRandomInt(getRandomInt(20)));
      getSequence(array, 'add', getRandomInt(2) + 1);
      console.info(array)
    }
    if (array.length <= 5){
      let arrayCopy = array;
      let lastInArray = arrayCopy.pop();
      array.push(lastInArray + differBy);
      getSequence(array, 'add', differBy);
    }
  }
}

console.info(getSequence([], 'add'));

Я не получаю stackoverflow ни в jsbin, ни просто вставляя его из jsbin в консоль. Код jsbin и ваш встроенный пример не совпадают

Uzer 31.08.2018 18:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
1
58
3

Ответы 3

let arrayCopy = array; на самом деле не копирует массив, поэтому, когда вы вставляете элемент, он просто уходит из исходного массива. Массив вообще не увеличивается в длину. Вам вообще не нужно выталкивать предмет.

function getSequence(array, mode, differBy){
  if (mode === 'add'){
    if (array.length >= 6){
      return array;
    }
     if (array.length === 0){
       array.push(getRandomInt(getRandomInt(20)));
       getSequence(array, 'add', getRandomInt(2) + 1);
       console.info(array)
    }
    if (array.length <= 5){      
      let lastInArray = array[array.length-1];
      array.push(lastInArray + differBy);
      getSequence(array, 'add', differBy);
    }
  }
}

getSequence([], 'add');

Правильно. Просто продолжение: теперь я нахожусь в первом блоке if, и массив имеет длину 6, и вы можете видеть это в журнале консоли, что массив там выглядит нормально. Но когда вернулся, он не определен. Как это может быть?

nikbad 31.08.2018 19:21

Возврат должен быть добавлен и к другим «если».

nikbad 31.08.2018 21:41

@ working4themiddleclass в возврате нет необходимости. Вы передаете ссылку на массив, чтобы вы могли ее использовать. Ваш первоначальный вызов должен быть var array = []; getSequence(array, 'add'), и тогда array будет иметь правильные данные. Если вы собираетесь использовать массив в качестве аккумулятора, вам не следует его возвращать

apokryfos 01.09.2018 07:47

Проблема с кодом, которым вы поделились, находится в let arrayCopy = array;, здесь он не создает новый массив, а делает ссылку arrayCopy на тот же массив, поэтому, когда вы pop() этот, он также pop() другой.

Чтобы создать новый массив с копией другого, вы должны использовать array.slice(). изменение, которое, кажется, заставляет ваш код работать.

Проблема в том, что вы не делаете копию массива - вы просто (в основном) настраиваете другую ссылку на тот же массив. Таким образом, arrayCopy.pop() также изменяет то, что видит переменная array, благодаря чему array никогда не растет.

Чтобы исправить свой код (сохранить его как можно ближе к тому, что он есть), вы можете использовать array.slice(), чтобы сделать фактическую копию данных.

Или более простое решение - установить lastInArray с помощью array.slice(-1).

Видеть

https://medium.com/@naveenkarippai/learning-how-references-work-in-javascript-a066a4e15600

и

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

Другие вопросы по теме