1.1 數據類型對拷貝的作用
1.11 數據類型:
(1)基礎數據類型(primitive data types):
基礎數據類型:簡單的數據端,基礎類型的數據有Number,Null,Boolean,Number and String。這五種基礎類型可以按值訪問,可以直接操作保存在變量的實際值(文字來源:JavaScript高級程序設計)
let test1 = "123";
let test2 = test1;
window.console.log("變化之前")
window.console.log(`test1-${test1}`)
window.console.log(`test2-${test2}`)
test2 = "321";
window.console.log("變化之後");
window.console.log(`test2-${test2}`)
window.console.log(`test1-${test1}`)
(2)引用數據類型(Composite data types):
引用數據類型數據是指那些可能多個值構成的對象,有Array,Object等,引用類型值保存在堆內存中,JavaScript不允許直接訪問內存中的位置,也不能直接操作對象的內存空間。操作對象時是直接操作對象的引用,而不是真正對象,所以會有深拷貝和淺拷貝的問題 (文字來源:JavaScript高級程序設計)
2.1 淺拷貝
淺拷貝賦值的變量,會同時指向同一個棧內存地址下的值,會影響所以變量下的賦值
//引用數據類型,只能拿到內存裏面的引用
let testObj1 = {
name:"testObject"
}
let testObj2 = testObj1
window.console.log("變化之前前");
window.console.log("testObj1");
window.console.log(testObj1)
window.console.log("testObj2");
window.console.log(testObj1)
testObj2.name = "testObj2";
window.console.log("變化之後");
window.console.log("testObj1");
window.console.log(testObj1)
window.console.log("testObj2");
window.console.log(testObj1)
3.1 深度拷貝
深拷貝不會拷貝引用類型的引用,而是將引用類型的值全部拷貝一份,形成一個新的引用類型,這樣就不會發生引用錯亂的問題,使得我們可以多次使用同樣的數據,而不用擔心數據之間會起衝突
3.2 使用方法:
3.21 方案一:使用Object.assign(target, source)方法
let testDeepObj1 = {
name:"testDeepObject"
}
let testDeepObj2 = Object.assign({},testDeepObj1);
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
3.22 方案二:使用ES6{…}
let testDeepObj1 = {
name:"testDeepObject"
}
let testDeepObj2 = {...testDeepObj1};
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
3.23 方案三:把賦值的值先利用JSON.stringfy()字符串化然後複製的時候在轉爲JSON.parse()
let testDeepObj1 = JSON.stringify({
name:"testDeepObject"
})
let testDeepObj2 = JSON.parse(testDeepObj1);
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
x.1 參考材料:
(1) 淺談JS深拷貝(深克隆)@郝晨光 :
https://www.jianshu.com/p/f4329eb1bace
(2)JavaScript高級程序設計
(3)How to differentiate between deep and shallow copies in JavaScript
https://www.freecodecamp.org/news/copying-stuff-in-javascript-how-to-differentiate-between-deep-and-shallow-copies-b6d8c1ef09cd/