一、浅拷贝
浅拷贝:一般指的是只拷贝对象的第一层,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址
拓展运算符
const originArr = ["a", [1, 2]]
const cloneArr = [...originArr]
cloneArr[0] = "b"
cloneArr[1][1] = 1
console.log(originArr) // ["a", [1, 1]]
console.log(cloneArr) // ["b", [1, 1]]
Object.assign
let originObj = { a: 'a', b: [1, 2]}
let cloneObj = Object.assign({}, originObj)
cloneObj.a = 'b'
cloneObj.b[0] = 2
console.log(originObj) // { a: 'a', b: [2, 2]}
console.log(cloneObj) // { a: 'b', b: [2, 2]}
slice(0)
const originArr = ["a", [1, 2]]
const cloneArr = originArr.slice(0)
cloneArr[0] = "b"
cloneArr[1][1] = 1
console.log(originArr) // ["a", [1, 1]]
console.log(cloneArr) // ["b", [1, 1]]
concat()
const originArr = ["a", [1, 2]]
const cloneArr = originArr.concat()
cloneArr[0] = "b"
cloneArr[1][1] = 1
console.log(originArr) // ["a", [1, 1]]
console.log(cloneArr) // ["b", [1, 1]]
二、深拷贝
深拷贝:深拷贝会开辟一个新的堆和栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
JSON.stringify/parse
// JSON.stringify 是将一个 JavaScript 值转成一个 JSON 字符串
// JSON.parse 是将一个 JSON 字符串转成一个 JavaScript 值或对象
const mySymbol = Symbol()
const originObj = {
name:'hhh',
age:undefined,
[mySymbol]:'mySymbol',
sayHello:function(){
console.log('Hello World')
}
}
console.log(originObj) // {name: 'hhh', age: undefined, Symbol(): 'mySymbol', sayHello: ƒ}
const cloneObj = JSON.parse(JSON.stringify(originObj))
console.log(cloneObj) // {name: 'hhh'}
!!! undefined、function、symbol 会在转换成 JSON 字符串的过程中被忽略
递归 深拷贝
function deepClone(source){
const targetObj = source.constructor === Array ? [] : {}
for(let keys in source){ // 遍历目标
if(source.hasOwnProperty(keys)){
if(source[keys] && typeof source[keys] === 'object'){
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepClone(source[keys]);
}else{ // 如果不是,就直接赋值
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}