一、浅拷贝
1、概念
对于浅拷贝而言,就是只拷贝对象的引用,而不深层次的拷贝对象的值,多个对象指向堆内存中的同一对象,任何一个修改都会使得所有对象的值修改,因为它们公用一条数据。
2、浅拷贝的实现
(1)直接赋值
let a = {
name : '张三',
age : '18'
}
let b = a;
b.name = '小谢';
console.log(a); //{name:'小谢',age:18}
console.log(b); //{name:'小谢',age:18}
(2)Object.assign(target[新数组], source[原数组])
var obj = {
name: '小谢',
age: 18,
hobby: {
a: '1'
}
}
var newObj = {};
Object.assign(newObj, obj);
console.log(newObj); // {name: "张三", age: 18, hobby: {…}}
newObj.hobby.a = '2';
console.log(obj.hobby.a); //2
console.log(newObj.hobby.a); //2
补充:
- 只拷贝源对象的自身属性(不拷贝继承属性)
- 不会拷贝对象不可枚举的属性
- undefined和null无法转成对象,他们不能作为Object.assign参数,但是可以作为源对象
- 属性名为Symbol 值的属性,可以被Object.assign拷贝
(3)使用jQuery中的$.extend();
var obj = {
name: '丽芳',
age: 23,
sex: '女',
hobby: {
a: '1'
}
}
var newObj = {};
$.extend(newObj, obj); //将obj复制到新对象中
console.log(newObj); //{name: "张三", age: 23, sex: "女", hobby: {…}}
newObj.hobby.a = '2';
console.log(obj.hobby.a); //2
console.log(newObj.hobby.a); //2
二、深拷贝
1、概念
深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突。
2、深拷贝的实现
(1)JSON.parse和JSON.stringify方法
- 支持深拷贝多层引用类型嵌套
- 不可以拷贝 undefined , function, RegExp 等类型的数据
对象:
var stu1={
name:'小红',
info:{
age:18
}
}
var str2=JSON.parse(JSON.stringify(stu1))
console.log("对象",str2); //{name:'小红',info:{age:18}}
数组:
//深拷贝 --数组
var a=[1,2,4,5,[6,7,8]]
var b=JSON.parse(JSON.stringify(a))
console.log("数组",b); //[1,2,4,5,[6,7,8]]
函数:
let obj = { "usr": "lisi", "age": 20, fn: function () { console.log('fn...'); } };
let obj2 = JSON.parse(JSON.stringify(obj));
obj2.usr = 'zhangsan';
console.log(obj, obj2); // { usr: 'lisi', age: 20, fn: [Function: fn] } { usr: 'zhangsan', age: 20 }
(2)ES6的扩展运算符实现克隆
var stu=[1,2,4,5,[6,7,8]]
var newstu = [...stu]
console.log("数组",newstu);
(3) 利用jQuery中的方法$.extend(true, ...);
- 实现对象的深拷贝; 第一个参数必须为true;
var obj = {
name: '张三',
age: 33,
sex: '男',
hobby: {
a: '1'
}
}
var newObj = {};
$.extend(true, newObj, obj);
console.log(newObj); //{name: "张三", age: 33, sex: "男", hobby: {…}}
newObj.hobby.a = '2';
console.log(obj.hobby.a); //1
console.log(newObj.hobby.a); //2
总结:这是目前本人经常使用的几种深|浅拷贝的方法。使用时,注意使用场景,选择合适的方法来进行操作。