javascript - למה ביצוע שינויים על עותק של מערך משפיע על המערך המקורי?


אני מסנן מערך תפריטים לפי הרשאה כאשר המשתמש מתחבר.
אני יוצר תפריט סטטי ואז נותן עותק של המערך לסינון.

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
  }

למה זה קורה? אם אני השתמשתי באופרטור הפצה ואני לא משתמש במערך המקורי [...menu.getMenu()].
רק אם אני מרענן את הדף menu.getMenu() חוזר לערך המקורי

עדכון 1
בתשובה להערות, הנה הפונקציה getMenu()

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;
  }

}

תשובה #1

אופרטור הפיזור יוצר העתק שטחי. אם התוכן של תפריט היה אובייקטים, אז שינוי האובייקטים הללו במערך העתק יגרום לשינוי האובייקטים הללו במערך המקורי (או טכנית, שני המצביעים הללו מתייחסים לאותו אובייקט):

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)

תשובה #2

תודה לתגובתו של איוון
עכשיו עשיתי שכפול עמוק בעקבותיה

const cloned = menu.getMenu().map(x => Object.assign({}, x));
    console.log('cloned ', cloned)
    this.menuItems = this.permissionService.filterMenuByTopic(cloned);

אחת התשובות שמצאתי כאן קישור