深拷贝 & 浅拷贝
众所周知,Object是引用数据类型,存储在内存的堆中,浅拷贝只是拷贝了另一个对象的内存地址,所以在修改时会同时修改另一个对象,而深拷贝会开辟新的内存地址,所以不会影响另一个对象
浅拷贝
let obj1 = {a:'1',b:{c:1}}
// 直接赋值
let obj2 = obj1
// 使用Object.assign
//Object.assign()拷贝的是属性值。假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值
let obj3 = Object.assign({},obj1)
深拷贝
// JSON.parse && JSON.stringify
// 性能最高,速度最快,但是只能拷贝纯json
function deepClone(obj){
let str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj)
newobj = JSON.parse(str)
} else {
for(let i in obj){
newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]
}
}
return newobj
}
// 递归
function deepClone(initalObj, finalObj ={}) {
for (let i in initalObj) {
let prop = initalObj[i]
if(prop === finalObj) {
continue
}
if (typeof prop === 'object') {
finalObj[i] = (prop.constructor === Array) ? [] : {}
arguments.callee(prop, finalObj[i]);
} else {
finalObj[i] = prop
}
}
return finalObj
}
// Object.create()
function deepClone(initalObj, finalObj) {
let obj = finalObj || {}
for (let i in initalObj) {
let prop = initalObj[i]
if(prop === obj) {
continue
}
if (typeof prop === 'object') {
obj[i] = (prop.constructor === Array) ? [] : Object.create(prop)
} else {
obj[i] = prop
}
}
return obj
}
// History API
function deepClone(obj) {
const oldState = history.state
history.replaceState(obj, document.title)
const copy = history.state
history.replaceState(oldState, document.title)
return copy
}
//MessageChannel
//异步方法,用时需注意
const obj = ...
const clone = await deepClone(obj)
function deepClone(obj) {
return new Promise(resolve => {
const {port1, port2} = new MessageChannel()
port2.onmessage = ev => resolve(ev.data)
port1.postMessage(obj)
});
}
// lodash 中的方法
function deepClone(obj) {
var copy;
if (null == obj || "object" != typeof obj) return obj;
if (obj instanceof Date) {
copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
if (obj instanceof Array) {
copy = [];
for (var i = 0, len = obj.length; i < len; i++) {
copy[i] = deepClone(obj[i]);
}
return copy;
}
if (obj instanceof Function) {
copy = function() {
return obj.apply(this, arguments);
}
return copy;
}
if (obj instanceof Object) {
copy = {};
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = deepClone(obj[attr]);
}
return copy;
}
throw new Error("Unable to copy obj as type isn't supported " + obj.constructor.name);
}