var value = 10;
var valueCopy = value;
valueCopy = 1000
console.log(value, valueCopy) // 10 1000
以上value结果的值没有随着valueCopy的改变而改变是因为数字,字符串是原始值,当重新给它赋值时不会在原地址修改而是新开一块地址
引用类型就是指向同一地址{}对象
1.浅拷贝: 只复制引用,而未复制真正的值(指向同一个地址数据,一个改变另一个也会改变)
直接赋值/Object.assgin()
var arr1 = [1,2,3,4,5];
var arr2 = arr1;
console.log(arr1, arr2) // [1,2,3,4,5] [1,2,3,4,5]
arr1[0] = 'hello'
arr2[1] = 'jack'
console.log(arr1, arr2) // ['hello','jack',3,4,5] ['hello','jack',3,4,5]
var obj1 = {a:1, b:2}
var obj2 = Object.assign(obj1)
console.log(obj1, obj2) // {a:1, b:2} {a:1, b:2}
obj1.a = 'hello'
obj2.b = 'jack'
console.log(obj1, obj2) // {a:'hello', b:'jack'} {a:'hello', b:'jack'}
2.深拷贝:复制真正的值(一个改变互相不影响)
使用JSON.parse(JSON.stringty())/Object.assgin()/es6解构/自己封装函数赋值
2.1使用JSON.parse(JSON.stringty()),得到一个全新的{}对象,和之前的对象地址是不相连的
缺点:有些类型的值是不支持的,不支持undefined,NaN,Infinity
var obj1 = {a: 1, b: 2}
var obj2 = JSON.parse(JSON.stringty(obj1))
console.log(obj1, obj2) // {a: 1, b: 2} {a:1, b: 2}
obj1.a = 'hello';
obj2.b = 'jack'
console.log(obj1, obj2) // {a: 'hello', b: 2} {a:1, b: 'jack'}
2.2使用Object.assgin() 不适用于对象里面有数组的{a: 1, b: 2, arr: [1, 2, 3]}
对象:
var obj3 = {a: 1, b: 2}
var obj4 = Object.assign({}, obj3) // 把obj3复制一份与新对象合并一起
console.log(obj3, obj4) // {a: 1, b: 2} {a:1, b: 2}
obj3.a = 'hello'
obj4.b = 'jack'
console.log(obj1, obj2) // {a: 'hello', b: 2} {a:1, b: 'jack'}
数组:
arr1 = [1,2,3,4]
arr2 = Object.assign([], arr1)
console.log(arr1,arr2) // (4)[1, 2, 3, 4] (4) [1, 2, 3, 4]
arr1[0] = 'hello'
arr2[1] = 'jack'
console.log(arr1, arr2) // (4) ['hello', 2, 3, 4] (4) [1, 'jack', 3, 4]
2.3使用es6解构
不适用于对象里面有数组的{a: 1, b: 2, arr: [1, 2, 3]}
var obj5 = {a: 1, b: 2}
var obj6 = {...obj5}
obj5.a = 'hello'
obj6.b = 'jack'
console.log(obj5, obj6) // {a: 'hello', b: 2} {a: 1, b: 'jack'}
----------优化对象里有数组的----------
var obj5 = {a: 1, b: 2, arr: [1, 2, 3, 4]}
var obj6 = {...obj5, arr: obj5.arr.map(item => item)} // map返回新数组,相当于 arr: [xxx]不是赋值是开辟了新数组新地址
// console.log(obj5, obj6)
obj5.a = 'hello'
obj6.b = 'jack'
obj5.arr[0] = 'name'
obj6.arr[0] = 'rose'
console.log(obj5, obj6) // {a: 'hello', b: 2, arr: ['name', 2, 3, 4]} {a: 1, b: 'jack', arr: ['rose', 2, 3, 4]}
2.4写个函数来复制(递归函数)
var obj5 = {a: 1, b: 2, arr: [1,2,3,4,5]}
function copyObj(obj){
var newObj = {}
for (var key in obj) {
newObj[key] = obj[key]
}
return newObj
}
// 优化
function copyObj(obj){
/* if (Array.isArray(obj)) {
var newObj = [];
} else {
var newObj = {};
}*/
Array.isArray(obj) ? var newObj = [] : var newObj = {}
for (var key in obj) {
if (typeof obj[key] == 'object') {
newObj[key] = copyObj(obj[key])
} else {
newObj[key] = obj[key]
}
}
return newObj
}
var obj6 = copyObj(obj5)
// obj6.arr = ['h','e', 'l']
console.log(obj5, obj6) // {a: 1, b: 2, arr: Array(5)} {a: 1, b: 2, arr: Array(5)}
2.5数组深拷贝 array.concat(),array.slice(), Array.from(array),展开运算符 把括号内的数组内容追加到后面
var list = ['jack', 'rose'];
var listCopy = [].concat(list)
var listCopy = list.slice() // 使用slice不传参的话会返回一个新的数组,并且包含所有从头到尾的所有元素,即使改变也不会改变原数组
var listCopy = Array.from(list) // 不影响原数组
var listCopy = [...list] // 展开运算符不影响原数组
listCopy.push('海绵宝宝', '派大星')
console.log(list, listCopy) // (2) ['jack', 'rose'] (4) ['jack', 'rose', '海绵宝宝', '派大星']
如果改为引用类型就是浅拷贝
var list = [{jack: 'rose'}]
var listCopy = [...list]
listCopy[0].jack = 'luxi'
console.log(list, listCopy) // [{jack: 'luxi'}] [{jack: 'luxi'}]