iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
自我挑戰組

Vue.js 從零開始系列 第 7

Vue.js 從零開始:物件參考 深拷貝 淺拷貝

資料處理是JavaScript非常重要的一環,如果觀念不正確,常常會卡在那邊,就算可以運行了,也不知道原理是什麼,本篇就來複習一下觀念。


資料處理中有一項叫做物件參考特性,是很多新手常會碰到的問題點,特性為物件是以傳參考的形式賦值,請看下面範例:

const obj = {
  name: '老王',
  data: {}
}
const obj2 = obj;
obj2.name = '小黃';

console.log(obj.name,obj2.name)

結果為 obj.name 為小黃,obj2.name 也是小黃,原本的name也被改變了,來畫張圖說明會什麼會這樣。
https://ithelp.ithome.com.tw/upload/images/20210919/20118347PbWSTZmelx.png

01指的是obj的物件,裡面有name和data屬性,注意data是一個物件,所以另外只指向到02,obj2也是指向第一個框框,所以obj2.name會一直改變obj.name,就算另外再新增新變數,結果也是一樣。

再來把 a 物件丟到函式當參數看結果會不會一樣呢:
https://ithelp.ithome.com.tw/upload/images/20210919/20118347X9PjKBKlYQ.png
console.log 結果是 true,就算丟到函式裡面還是有傳參考的特性在。

再來一個陷阱題範例:

var a = {
  name: 'a',
}

function Data(param) {
  return {
    name: param.name
  }
}

var b = Data(a);

console.log(a === b);

請問console.log的結果會是一樣true嗎?





正確答案是false,畫張圖來說明:
https://ithelp.ithome.com.tw/upload/images/20210919/201183473Dga32w1py.png
Data(a)將參數a傳到函式Data(param)裡,這時return回傳了一個新物件,新物件裡面的值是複製原本a物件裡面的值,所以結果就會是false,關鍵在於這個新物件,增加一個新物件就代表不會延續舊物件的值了,為了解決這種傳參考的問題,有以下兩種方法:

  1. 淺層拷貝
const person = {
  name: '小王',
  obj:{},
}

const person2 = Object.assign({}, person);
const person3 = { ...person };
console.log(person === person2,person ===person3);
person2.obj.age = 16;

console.log(person,person2)

https://ithelp.ithome.com.tw/upload/images/20210920/20118347oH2NeWTQE2.png
person2.obj.age = 16,person裡面的obj被改變,當更深層的物件被改變時,淺拷貝就會失效,這時就要使用到深拷貝

2.深層拷貝

var a = {
  name: 'a',
}
function data(param){
  const newData = JSON.parse(JSON.stringify(param));
  return newData;
}
var b = data(a);

console.log(a === b);

JSON.stringfy 把Param物件轉字串,JSON.parse再轉回物件JSON格式,來消除參考位置。


/images/emoticon/emoticon13.gif


上一篇
Vue.js 從零開始:箭頭函式
下一篇
Vue.js 從零開始:var,let,const 傻傻分不清楚
系列文
Vue.js 從零開始30

尚未有邦友留言

立即登入留言