Почему метод pop() перестает работать при использовании в методе карты?

Я хочу перевернуть массив на месте без использования обратного метода. Я попробовал следующий код:

function reverseArray(arr) {
  return arr.map(() => {
    return arr.pop()
  })
}
console.info(reverseArray([1, 2, 3, 4]));
//logs [4,3,undefined,undefined]

Используя отладчик инструментов разработчика, это то, что регистрируется в консоли: (4) [4, 3, empty × 2].

arr.pop() возвращает неопределенное значение, если вызывается для пустого массива, но, насколько я понимаю, в этом случае он не должен быть пустым.

Вопрос: что происходит? Почему первые два элемента печатаются правильно, а остальные нет?

Вы удаляете элементы из массива, пока перебираете его.

Barmar 12.12.2020 00:14

Для массивов уже есть обратный метод. Зачем изобретать велосипед?

Taplar 12.12.2020 00:15
return arr[ arr.length - 1 - i ]; должен сделать работу
blex 12.12.2020 00:15

@Taplar Вопрос конкретно в том, чтобы не использовать этот метод.

ThexXTURBOXx 12.12.2020 00:15

Я понимаю. Если это для обучения, круто. В противном случае это просто пустая трата времени.

Taplar 12.12.2020 00:16

Вы не должны использовать map(), если хотите, чтобы результат был в исходном массиве. Он всегда возвращает новый массив.

Barmar 12.12.2020 00:31
Поведение ключевого слова "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) для оценки ваших знаний,...
1
6
461
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в том, что вы pop некоторые элементы и, следовательно, они больше не существуют в массиве. Итак, первые два элемента отмечены pop, а два других записаны в этих местах, но внутренне они тем временем больше не существуют.

Есть также много других (лучших) решений, подобных этому (из здесь):

function reverse (array) {
  var i = 0,
      n = array.length,
      middle = Math.floor(n / 2),
      temp = null;

  for (; i < middle; i += 1) {
     temp = array[i];
     array[i] = array[n - 1 - i];
     array[n - 1 - i] = temp;
  }
}
Ответ принят как подходящий

Вы удаляете элементы из массива, пока перебираете его. В документации говорится:

Диапазон элементов, обрабатываемых картой, устанавливается перед первым вызовом обратного вызова. ... Элементы, которые удаляются после начала вызова карты и до посещения, не посещаются.

Итак, map() определяет в начале, что он будет повторяться 4 раза, создавая массив из 4 элементов.

На первой итерации arr.pop() удаляет arr[3]. На второй итерации он удаляет arr[2].

Третья итерация ожидает обработки arr[2]. Но поскольку этот элемент больше не существует, он не вызывает функцию обратного вызова, а просто сохраняет undefined в массиве результатов. То же самое происходит и на четвертой итерации.

Вы можете перебрать копию массива.

function reverseArray(arr) {
  return [...arr].map(() => {
    return arr.pop()
  })
}
console.info(reverseArray([1, 2, 3, 4]));

Проблема с этим решением в том, что оно не на месте, как запрошено

ThexXTURBOXx 12.12.2020 00:26

Исходный код тоже не на месте. map() всегда создает новый массив.

Barmar 12.12.2020 00:28

Хотя это правда, вопрос требовал решения на месте. Вот почему мне было интересно

ThexXTURBOXx 12.12.2020 14:43

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