js變量復(fù)制,復(fù)雜類型存的是地址值,淺拷貝只是把地址值復(fù)制了一份,拷貝對(duì)象和原對(duì)象指向同一個(gè)地址, 一個(gè)改變也會(huì)影響另外一個(gè)
淺拷貝
- 對(duì)象復(fù)制
- Object.assign()
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2); // 返回 {a:1, b:2, c:3}
target // {a:1, b:2, c:3}
- ...obg 擴(kuò)展運(yùn)算符
深拷貝
- JSON,parse(JSON.stringify)
- 拷貝的對(duì)象的值中如果有函數(shù),undefined,symbol則經(jīng)過(guò)JSON.stringify()序列化后的JSON字符串中這個(gè)鍵值對(duì)會(huì)消失
- 無(wú)法拷貝不可枚舉的屬性焕檬,無(wú)法拷貝對(duì)象的原型鏈
- 拷貝Date引用類型會(huì)變成字符串
// let date = new Date()
// undefined
// DataTransfer
// ? DataTransfer() { [native code] }
// date
// Mon Dec 07 2020 10:48:10 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
// JSON.stringify(new Date())
// ""2020-12-07T02:48:58.265Z""
- 拷貝RegExp引用類型會(huì)變成空對(duì)象
- 對(duì)象中含有NaN、Infinity和-Infinity种冬,則序列化的結(jié)果會(huì)變成null
- 無(wú)法拷貝對(duì)象的循環(huán)應(yīng)用(即obj[key] = obj)
深拷貝實(shí)現(xiàn)
var obj = {
a: 2,
b: [1,2,3,{aa: 11, bb:22}],
c: function () {
console.log("cccc")
},
d: undefined,
e: 'e',
f: /^\d+$/
}
// let obj1 = JSON.parse(JSON.stringify(obj)) // 會(huì)丟失c的function 和d的undefined 正則({})/日期格式 會(huì)改變
// 方法1
function deepClone (obj) {
let objClone = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) { // 如果是私有屬性 不是原型上的才進(jìn)入
if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
deepClone(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
return objClone
}
let obj2 = deepClone(obj)
console.log(obj2)
// 方法2
function deepClone2 (obj) {
//過(guò)濾特殊情況
if (obj === null) return;
if (typeof obj != 'object') return obj;
if (obj instanceof RegExp) {
return new RegExp(obj)
}
// => 不直接創(chuàng)建空對(duì)象的目的,克隆的結(jié)果和之前保持相同的所屬類
let newObj = new obj.constructor;
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = deepClone2(obj[key])
}
}
return newObj;
}
let obj3 = deepClone2(obj);
console.log(obj3)