- 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用。
- 深拷贝拷贝多层,每一级别的数据都会拷贝。
浅拷贝
使用普通遍历来拷贝(浅拷贝)
var obj = {
id:1,
name:'andy',
msg:{
age:8
}
};
var o = {};
for( var k in obj ) { // k 是属性名 obj[k] 是属性值
o[k] = obj[k];
}
o.msg.age=20; //这样修改的话 obj中的msg里面的age也会跟着变化
使用ES6中的Object.assign(target,…sources)方法实现浅拷贝
Object.assign(o,obj); //相当于上面的for-in循环
深拷贝
使用递归来拷贝(深拷贝)
var obj = {
id:1,
name:'andy',
msg:{
age:8
}
};
var o = {};
//封装函数
function deepCopy(newobj,oldobj){
for( var k in oldobj ) { // k 是属性名 obj[k] 是属性值
var item = oldobj[k];
if(item instanceof Array){ //判断是不是数组要放在判断Object之前,因为数组也是对象类型
newobj[k] = [];
deepCopy(newobj[k],item);
}else if(item instanceof Object){ //分开判断数组和对象是因为他们的字面量不一样,数组是[],对象是{}
newobj[k] = {};
deepCopy(newobj[k],item);
}else{
newobj[k] = item;
}
}
}
deepCopy(o,obj);
o.msg.age=20; //这样修改 obj中的msg里面的age不会变化
使用Lodash工具库中的_.cloneDeep(value)方法进行深拷贝
Lodash官网
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);//false
jQuery拷贝对象
语法:
$.extend([deep], target, object1, [objectN])
- deep: 如果设为true 为深拷贝, 默认为false 浅拷贝
- target: 要拷贝的目标对象 (拷贝之后得到的对象)
- object1:待拷贝到第一个对象的对象。
- objectN:待拷贝到第N个对象的对象。
浅拷贝例子:
$(function() {
// 1.合并数据
var targetObj = {};
var obj = {
id: 1,
name: "andy"
};
$.extend(targetObj, obj);
console.log(targetObj); //{id:1,name:'andy'}
// 2. targetObj 里面原来属性名称相同的数据会被覆盖
var targetObj = {
id: 0
};
var obj = {
id: 1,
name: "andy"
};
$.extend(targetObj, obj);
console.log(targetObj); //{id:1,name:'andy'}
// 3. targetObj 里面原来属性名称相同的数据会被覆盖不同的会被保留
var targetObj = {
id: 0,
age:18
};
var obj = {
id: 1,
name: "andy"
};
$.extend(targetObj, obj);
console.log(targetObj); //{id:1,name:'andy',age:18}
})
深拷贝例子:
var targetObj = {
id: 0,
msg: {
sex: '男'
}
};
var obj = {
id: 1,
name: "andy",
msg: {
age: 18
}
};
//深拷贝把里面的数据完全复制一份给目标对象 如果里面有不冲突的属性,会合并到一起
$.extend(true, targetObj, obj);
console.log(targetObj); // {id:1,name:'andy',msg :{sex: "男", age: 20}}
targetObj.msg.age = 20;
console.log(obj); //修改targetObj里面msg的属性值不会影响obj的
WebAPIs中的node克隆节点
语法:
node.cloneNode();
返回值是调用该方法的节点的一个副本。
注意:
1.如果括号参数为空或者false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
2.如果括号参数为true,则是深度拷贝,会复制节点本身以及里面所有的子节点。
例子:
<ul>
<li>aaa</li>
<li>bbb</li>
<li>ccc</li>
</ul>
<script>
var ul = document.querySelector('ul');
// 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
// 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
var newli = ul.children[0].cloneNode(true); //这里是true深拷贝,会克隆里面的文字内容。
ul.appendChild(newli);
</script>