Привет, я играю с node.js и Javascript для предстоящего проекта. У меня есть массив объектов шаблона под названием templateValues.
Теперь я хотел бы скопировать эти два объекта с измененными идентификаторами в новый массив myArray.
let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];
for (let index = 0; index < 10; index++) {
myArray = myArray.concat(templateValues.map(e => {
e.id = Math.random(); // suppose this gives a unique id
return e;
}).slice(0));
}
console.info(myArray);ВЫХОД:
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
...
Почему все я бы одинаковы, даже если я делаю срез (0) измененного массива templateValues, чтобы получить «копию данных» ?!
slice() делает мелкую копию, а не глубокую копию.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Когда вы вызываете slice, вы изменяете объект массива, а не его содержимое. В вашем примере нет строк кода, которые клонируют базовый объект, и поэтому, когда вы устанавливаете e.id = Math.random(), вы редактируете один и тот же объект снова и снова.
Исправление здесь состоит в том, чтобы клонировать e перед его изменением. Попробуйте Object.assign({}, e) перед редактированием, чтобы сделать мелкую копию каждого элемента.
См. Пример ниже:
let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];
for (let index = 0; index < 10; index++) {
myArray = myArray.concat(templateValues.map(e => {
const eCopy = Object.assign({}, e, {id: Math.random()})
return eCopy;
}).slice(0));
}
console.info(myArray);Вы также можете использовать Синтаксис распространения объекта ES2018 для достижения того же результата.
Просто замените Object.assign на {...e, id: Math.random()}
Другой ответ и комментарий уже объясняют проблему, поэтому я просто предлагаю решение - вы можете использовать ниже, чтобы получить то, что вам нужно, длину нового массива можно установить так, как вы хотите, типы будут повторяться в тот же порядок вашего исходного массива
let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
const newArr = Array.from ({length: 10}, (_, i) => ({
id: Math.random(),
type: templateValues[i % templateValues.length].type
}));
console.info(newArr);
Вы изменяете исходные ссылки на объекты, а не добавляете новые объекты в список. Все идентификаторы будут одинаковыми.