最近在学习c++,以前从来没接触过也没想到过深拷贝和浅拷贝。c++里有深拷贝和浅拷贝,那么其它语言中应该也有。
本文参考:
https://juejin.im/post/59ac1c4ef265da248e75892b
我觉得js中对象复制应该分三种:
1.赋值
2.浅拷贝
3.深拷贝
赋值可以说是最浅得一层了,啥都是原来对象的,不管是基本数据类型(undefined,boolean,number,string,null)还是引用类型。
修改赋值后的对象的数据,那么原对象的数据也会修改。就相当于是个指针指向了复制的对象。
浅拷贝:
var obj1 = {
'name' : 'zhangsan',
'age' : '18',
'language' : [1,[2,3],[4,5]],
};
var obj2 = obj1; //赋值
var obj3 = shallowCopy(obj1); //浅拷贝
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
浅拷贝只是将原对象的属性拷贝了过来,修改基本数据类型时原对象不会改变,但是修改引用类型数据时,原对象会改变的。下面时zepto中的深拷贝的代码:
// 内部方法:用户合并一个或多个对象到第一个对象
// 参数:
// target 目标对象 对象都合并到target里
// source 合并对象
// deep 是否执行深度合并
function extend(target, source, deep) {
for (key in source)
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
// source[key] 是对象,而 target[key] 不是对象, 则 target[key] = {} 初始化一下,否则递归会出错的
if (isPlainObject(source[key]) && !isPlainObject(target[key]))
target[key] = {}
// source[key] 是数组,而 target[key] 不是数组,则 target[key] = [] 初始化一下,否则递归会出错的
if (isArray(source[key]) && !isArray(target[key]))
target[key] = []
// 执行递归
extend(target[key], source[key], deep)
}
// 不满足以上条件,说明 source[key] 是一般的值类型,直接赋值给 target 就是了
else if (source[key] !== undefined) target[key] = source[key]
}
// Copy all but undefined properties from one or more
// objects to the `target` object.
$.extend = function(target){
var deep, args = slice.call(arguments, 1);
//第一个参数为boolean值时,表示是否深度合并
if (typeof target == 'boolean') {
deep = target;
//target取第二个参数
target = args.shift()
}
// 遍历后面的参数,都合并到target上
args.forEach(function(arg){ extend(target, arg, deep) })
return target
}