javascript - Varför påverkar ändringar i en kopia av en array den ursprungliga arrayen?
Jag filtrerar menyarrayen efter behörighet när användaren har loggat in.
Jag genererar en statisk meny och ger sedan en kopia av arrayen att filtrera.
constructor(public menu: MenuService, public permissionService: PermissionService) {
console.log(menu.getMenu()) // this changes after filtering below
this.menuItems = this.permissionService.filterMenuByTopic([...menu.getMenu()]); // here I'm using a copy
}
Varför händer detta? Om jag har använt spridningsoperatorn och jag inte använder den ursprungliga arrayen [...menu.getMenu()].
Endast om jag uppdaterar sidan returnerar menu.getMenu() till ursprungligt värde
UPD 1
svarar på kommentarerna, här är getMenu() funktionen
import { Injectable } from '@angular/core';
@Injectable()
export class MenuService {
menuItems: Array<any>;
constructor() {
this.menuItems = [];
}
addMenu(items: Array<{
text: string,
heading?: boolean,
link?: string, // internal route links
elink?: string, // used only for external links
target?: string, // anchor target="_blank|_self|_parent|_top|framename"
icon?: string,
alert?: string,
submenu?: Array<any>
}>) {
items.forEach((item) => {
this.menuItems.push(item);
});
}
getMenu() {
return this.menuItems;
}
}
Svar #1
Spridningsoperatorn skapar en ytlig kopia. Om innehållet i en meny var objekt, kommer ändring av dessa objekt i en kopierad array att ändra dessa objekt i den ursprungliga arrayen (eller tekniskt sett, de två referenserna är för samma objekt):
const obj1 = {
val: 1
}
const obj2 = {
val: 2
}
const obj3 = {
val: 3
}
const arr = [obj1, obj2, obj3]
// creating a copy with the spread operator
const copy = [...arr]
// changing the second element in the copy
copy[1].val = 22
// the element in the original array is changed too
console.log(arr)Svar #2
Tack vare Ivans kommentar
har jag gjort en djup kopia genom att följa
const cloned = menu.getMenu().map(x => Object.assign({}, x));
console.log('cloned ', cloned)
this.menuItems = this.permissionService.filterMenuByTopic(cloned);
En av de svar jag har hittat här länk
