和原数据是否指向同一个地址 | 第一层数据(基础类型数据) | 第二层数据(原数据中的再次使用引用类型的数据) | |
---|---|---|---|
赋值 | 是 | 会改变 | 会改变 |
浅拷贝 | 否 | 不会改变 | 一起改变 |
深拷贝 | 否 | 不会改变 | 不会改变 |
直接赋值
let obj = { a: '1',b: { two: '2' }, c: '3' }
let copyObj = {}
copyObj = obj
console.log(copyObj === obj) // true 说用两个引用类型指向同一个内存地址
copyObj.a = 'change'
obj.b.two = 'b-change'
console.log(copyObj, obj)
/*
copyObj 输出
{
a: "change"
b: {two: 'b-change'}
c: "3"
}
obj 输出
{
a: "change"
b: {two: 'b-change'}
c: "3"
}
*/
浅拷贝
方法
方法一: Object.assign()
方法二:展开运算符(…)
方法三:Array.prototype.concant()
方法四:Array.prototype.slice()
方法五:使用函数库loash的_clone方法
let obj = { a: '1',b: { two: '2' }, c: '3' }
let copyObj = {}
copyObj = Object.assign({}, obj)
console.log(copyObj === obj) // false 说用两个引用类型指向不同的内存地址
copyObj.a = 'change'
obj.b.two = 'b-change'
console.log(obj, copyObj)
/*
obj 输出
{
a: "1"
b: {two: 'b-change'}
c: "3"
}
copyObj 输出
{
a: "change"
b: {two: 'b-change'}
c: "3"
}
*/
let arr = [1,2,3,{a: 4}]
let copyArr = []
copyArr = [...arr]
copyArr[1] = 100 copyArr[3].a = 400
consle.log(arr, copyArr)
/*
arr 输出
[1, 2, 3, {a: 400}]
copyArr 输出
[1, 100, 3, {a: 400}]
*/
深拷贝
方法
方法一:JSON.parse(JSON.stringify)
这种方法可以处理数组或者对象,但是不能处理函数和正则,因为已经处理之后,正则会变成一个空对象,函数会变成null
方法二: 函数库loash的_cloneDeep方法
方法三: JQuery.extend方法
let obj = { a: '1',b: { two: '2' }, c: '3' }
let copyObj = {}
copyObj = JSON.parse(JSON.stringify(obj))
copyObj.a = 'change' copyObj.b.two = 'b-change'
console.log(obj, copyObj)
/*
obj 输出
{ a: '1',b: { two: '2' }, c: '3' }
copyObj 输出
{ a: 'change',b: { two: 'b-change' }, c: '3' }
*/