浅拷贝:复制对象的内存地址和值都一样,值发生改变,复制的对象也会改变
深拷贝:复制对象的值一样,内存地址和被复制对象完全不同,彼此不影响
浅拷贝的几种方式
- 直接赋值
let arr = [1,2,3,4]
let arrCopy = arr
arrCopy[0] = 'Jerry'
console.log(arr) //[ "Jerry",2,3,4]
console.log(arrCopy) //[ "Jerry",2,3,4]
- Object.assign
此方法可以将多个源对象可枚举属性拷贝给目标对象,并返回目标对象,但只是拷贝对象的引用,而不是本身
let arr = [[1,2],[3,4]]
let arrCopy = Object.assign([],arr)
arrCopy[0][0] = 5
console.log(arr[0][0]) // 5
console.log(arrCopy[0][0]) // 5
let obj = { a: {a: "hello",} b: 21 }
let objCopy = Object.assign({}, obj)
objCopy.a.a = "word"
console.log(obj.a.a) // "word"
- 数组的Array.from、slice、concat
Array.from其实和Object.assign、数组的slice、concat一样,只能实现一维数组或一级对象的深拷贝,多维数组或多级对象就不行了,所以我还是将这些方法划分为浅拷贝
let arr = [1,2,3,4]
let arrCopy = Array.from(arr)
arrCopy[0] = 5
console.log(arr[0]) //1
console.log(arrCopy[0]) //5
let arr2 = [[1,2],[3,4]]
let arrCopy2 = Array.from(arr2)
arrCopy2[0][0] = 5
console.log(arr2[0][0]) //5
console.log(arrCopy2[0][0]) //5
let obj = { a: {a: "hello"}, b: 21 }
let objCopy = Object.assign({}, obj)
objCopy.a.a = "word"
objCopy.b = 1
console.log(obj.a.a) // "word"
console.log(obj.b) // 21
深拷贝的几种方式
- JSON.parse和JSON.stringify
let arr = [[1,2],[3,4]]
let arrCopy = JSON.parse(JSON.stringify(arr))
arrCopy[0][0] = 5
console.log(arr[0][0]) // 1
console.log(arrCopy[0][0]) // 5
let obj = { a: {a: "hello"}, b: 21 }
let objCopy = JSON.parse(JSON.stringify(obj))
objCopy.a.a = "word"
objCopy.b = 1
console.log(obj.a.a) // "hello"
console.log(obj.b) // 21
- 遍历对象和递归
function deepCopy(obj) {
let data = Array.isArray(obj) ? [] : {}
for (let key in obj) {
if (typeof obj[key] == "object") {
data[key] = deepCopy(obj[key])
} else {
data[key] = obj[key]
}
}
return data
}
let arr = [[1,2],[3,4]]
let arrCopy = deepCopy(arr)
arrCopy[0][0] = 5
console.log(arr[0][0]) // 1
console.log(arrCopy[0][0]) // 5
let obj = { a: {a: "hello"}, b: 21 }
let objCopy = deepCopy(obj)
objCopy.a.a = "word"
objCopy.b = 1
console.log(obj.a.a) // "hello"
console.log(obj.b) // 21
- Jquery.extend
此方法需要引入第三方库jquery.js