iT邦幫忙

2021 iThome 鐵人賽

DAY 20
2
Modern Web

Angular 常見問題大小事系列 第 20

Angular 淺拷貝之...日記文

  • 分享至 

  • xImage
  •  

又踩雷啦啊哈哈哈哈哈。
來重現一下遇到的情境吧


bug 出現


export class AppComponent implements OnInit {
  fruit : any = {
    apple: {},
    banana: {},
  };

  ngOnInit() {
    this.fruit = {
      apple: {
        id: 1,
        isSelect: false,
      },
      banana: {
        id: 2,
        isSelect: false,
      },
    };
  }

  onClick(isSelect: boolean) {
    this.fruit = {
      apple: {
        id: 1,
        isSelect,
      },
    };
  }

  • 一開始建了一個 fruit 的物件,裡面有 applebanana 這兩樣空物件
  • OnInit 時,賦予了 applebanana
  • 當我按下 button Click 的 時後, apple 裡的 isSelect 為 true

啊!踩到雷了!

如圖,按下去後,噴錯了!

發現 banana 的 id 不見了,原來是我把 this.fruit 整個值給改掉了
本以為上述的寫法,只會修改我有填的值 XD


解法:解構賦值 => 淺拷貝(shallow copy)

這裡我使用了 js 裡的解構賦值處理,也可以用來做 淺拷貝(shallow copy)
將 onClick 的寫測改成這樣

onClick(isSelect: boolean) {
  this.fruit = {
    ...this.fruit,  // shallow copy
    apple: {
      id: 1,
      isSelect,
    },
  };
}

來看看成果。嗯...沒噴錯了 XD 結案!


筆記:深拷貝 (deep copy)

將原本的物件轉字串後再轉成物件,就會又是全新的一個物件了!

JSON.parse(JSON.stringify(objArray));

objArray 為要帶入的物件


後記:

本來以為是淺(深)拷貝的問題,後來仔細一看,原來是我自己搞錯了,將 this.fruit 裡面的整個值都蓋掉,所以才會噴錯,不過也剛好再度對深拷貝與淺拷貝的這件事加深印象。

案例:https://stackblitz.com/edit/angular-ivy-wvmptw

參考資料:
变量的解构赋值
深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?
關於 JS 中的淺拷貝(shallow copy)以及深拷貝(deep copy)


上一篇
使用 Angular 做檔案編碼檢測 (detect-encoding)
下一篇
如何在 Angular 取得當前頁面的絕對路徑
系列文
Angular 常見問題大小事31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言