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深拷贝(深克隆)@郝晨光 :
(2)JavaScript高级程序设计
(3)How to differentiate between deep and shallow copies in JavaScript