мутирующий массив с forEach

Мне поручили написать метод forEach, который изменяет строковые значения для каждого элемента массива.

Вот пример:

candy = ['snickers', 'mars', 'three muskateers']

candy.forEach(function(e){
  e.toUpperCase());
});

Я протестировал forEach с помощью ведения журнала консоли, и, похоже, я получаю возвращаемые значения, которые хочу.

candy.forEach(function(e){
  console.log(e.toUpperCase());

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

console.log(candy);

Связано ли это со строками как с примитивными типами данных? Может кто-нибудь, пожалуйста, помогите мне лучше понять?


person space_ninja    schedule 30.12.2016    source источник
comment
Вам нужно присвоить новое значение каждому элементу массива, toUpperCase не изменит исходный элемент   -  person user2314737    schedule 30.12.2016


Ответы (3)


В вашем случае исходный массив не изменяется.

Вам нужно создать отдельный массив и сохранить значения в верхнем регистре внутри для каждого в отдельном массиве.

Ваш код (измененный):

candy = ['snickers', 'mars', 'three muskateers']
var candyModified = Array();
candy.forEach(function(e){
    candyModified.push(e.toUpperCase());
});
console.log(candyModified);
person AkikG    schedule 30.12.2016

Когда вы попытались напечатать массив candy, вы не получили никаких изменений, потому что обе функции map и forEach не влияют на исходный массив и не изменяют его.

Используя forEach:

candy = ['snickers', 'mars', 'three muskateers'];

console.log(candy.forEach(v => v.toUpperCase()));

console.log(candy);

Используя функцию map:

candy = ['snickers', 'mars', 'three muskateers'];

console.log(candy.map(v => v.toUpperCase()));

console.log(candy);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Однако вы можете заметить, что функция forEach возвращает undefined, потому что forEach ничего не возвращает. Он просто выполняет заданное действие над массивом, а функция map возвращает совершенно новый массив с измененными элементами.

Из-за того, что функция forEach, как и map, не изменяет исходный массив, если вы хотите изменить исходный массив, вы можете сделать это, присвоив измененный массив функцией map вашей переменной candy.

candy = ['snickers', 'mars', 'three muskateers'];

candy = candy.map(v => v.toUpperCase());

console.log(candy);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Обратите внимание: если вы укажете здесь forEach, console.log(candy) вернет undefined.

candy = ['snickers', 'mars', 'three muskateers'];

candy = candy.forEach(v => v.toUpperCase());

console.log(candy);
.as-console-wrapper { max-height: 100% !important; top: 0; }

person kind user    schedule 30.12.2016

Чтобы изменить его, вы должны использовать 3-й аргумент forEach или использовать сам candy. Как это:

Метод 1 — 3-й аргумент

candy = ['snickers', 'mars', 'three muskateers']

candy.forEach(function(el, i, arr){
  arr[i] = el.toUpperCase();
});

console.log(candy);

Способ 2 - используйте candy

candy = ['snickers', 'mars', 'three muskateers']

candy.forEach(function(el, i){
  candy[i] = el.toUpperCase();
});

console.log(candy);

person Noitidart    schedule 30.12.2016