資料處理是JavaScript非常重要的一環,如果觀念不正確,常常會卡在那邊,就算可以運行了,也不知道原理是什麼,本篇就來複習一下觀念。
資料處理中有一項叫做物件參考特性
,是很多新手常會碰到的問題點,特性為物件是以傳參考的形式賦值,請看下面範例:
const obj = {
name: '老王',
data: {}
}
const obj2 = obj;
obj2.name = '小黃';
console.log(obj.name,obj2.name)
結果為 obj.name 為小黃,obj2.name 也是小黃,原本的name也被改變了,來畫張圖說明會什麼會這樣。
01指的是obj的物件,裡面有name和data屬性,注意data是一個物件,所以另外只指向到02,obj2也是指向第一個框框,所以obj2.name會一直改變obj.name,就算另外再新增新變數,結果也是一樣。
再來把 a 物件丟到函式當參數看結果會不會一樣呢:
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,畫張圖來說明:
Data(a)將參數a傳到函式Data(param)裡,這時return回傳了一個新物件
,新物件裡面的值是複製原本a物件裡面的值,所以結果就會是false,關鍵在於這個新物件,增加一個新物件就代表不會延續舊物件的值了,為了解決這種傳參考的問題,有以下兩種方法:
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)
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格式,來消除參考位置。