首页 > 解决方案 > 为什么更改数组的副本会影响原始数组?

问题描述

用户登录后,我按权限过滤菜单数组。
我生成静态菜单,然后将数组副本提供给过滤器。

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()返回原始值

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

}

标签: javascriptangulartypescriptecmascript-6

解决方案


扩展运算符创建一个浅拷贝。如果菜单的内容是对象,那么更改副本数组中的这些对象将更改原始数组中的那些对象(或者从技术上讲,这两个引用是针对同一个对象的):

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)


推荐阅读