// implements Object.assign
// fix `Cannot resolve module 'babel-runtime/core-js/object/assign'`
export function assign(dest, ...srcs) {
srcs.reverse().forEach(src => {
for (const k in src) {
if (src.hasOwnProperty(k)) {
dest[k] = src[k]
}
}
})
return dest
}
// detail: https://www.zhihu.com/question/23031215
// about deepCopy: http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/
export function deepClone(obj) {
let str
let 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' ? deepClone(obj[i]) : obj[i]
}
}
return newobj
}
更好的实现可看这篇文章:
【进阶4-3期】面试题之如何实现一个深拷贝 - 掘金juejin.imJSON.parse深拷贝
先将一个对象转为json对象。然后再解析这个json对象
let obj = {a:{b:22}};
let copy = JSON.parse(JSON.stringify(obj));
- 优点: 代码写起来比较简单
- 缺点:你先是创建一个临时的,可能很大的字符串,只是为了把它重新放回解析器。另一个缺点是这种方法不能处理循环对象 , 如下面的循环对象用这种方法的时候会抛出异常;
- 诸如 Map, Set, RegExp, Date, ArrayBuffer 和其他内置类型在进行序列化时会丢失。
let a = {};
let b = {a};
a.b = b;
let copy = JSON.parse(JSON.stringify(a));
var a = [
1,
function(){ /*..*/ },
2,
function(){ /*..*/ }
];
JSON.stringify( a ); // "[1,null,2,null]"
JSON.stringify( a, function(key,val){
if (typeof val == "function") {
// 函数的ToBoolean强制类型转换
return !!val;
}
else {
return val;
}
} );
// "[1,true,2,true]"
SON.stringify(..) 在对象中遇到值为 undefined、function 和 symbol 时会自动将这个字段忽略,在数组中则会返回 null(以保证单元位置不变)。
可以通过第二个参数将函数转换为其它可显示的内容
lodash深拷贝
https://github.com/lodash/lodash/blob/master/cloneDeep.jsgithub.com示例:
注意option的深度, 因为 Object.assign或者lodash._assign是浅拷贝, text拷贝不到。
而我们结构转换图表中的标题是依赖 title.text传入的,所以这里肯定会报错.