为什么需要DeepCopy:
在JS里,除Array和Object之外的数据类型的复制可以直接通过等号=来实现,但Array和Object类型的数据通过等号只是起引用作用,指向的是同一块内存地址。当源数据改变,引用的数据也同时会发生变化。
JS实现DeepCopy的方式:
1.使用jq的$.extend(true, target, obj)
2.newobj = Object.create(sourceObj) // 但是这个是有个问题就是 newobj的更改不会影响到 sourceobj但是 sourceobj的更改会影响到newObj
3.newobj = JSON.parse(JSON.stringify(sourceObj)) // undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。但是在平时的开发中JSON.parse(JSON.stringify(obj))已经满足90%的使用场景了。
4.递归
1)寻常递归
var deepCopy = function(o) {
if (o instanceof Array) { //先判断Array
var n = [];
for (var i = 0; i < o.length; ++i) {
n[i] = deepCopy(o[i]);
}
return n;
} else if (o instanceof Object) {
var n = {}
for (var i in o) {
n[i] = deepCopy(o[i]);
}
return n;
} else {
return o;
}
}
2)Vuex源码中使用的方法
function deepCopy (obj, cache = []) {
function find (list, f) {
return list.filter(f)[0]
}
if (obj === null || typeof obj !== 'object') {
return obj
}
const hit = find(cache, c => c.original === obj)
if (hit) {
return hit.copy
}
const copy = Array.isArray(obj) ? [] : {}
cache.push({
original: obj,
copy
})
Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key], cache)
})
return copy
}