js对象的浅拷贝和深拷贝的实现方法

一、浅拷贝

 浅拷贝:只拷贝一层数据; 复杂数据只是拷贝地址;

注意:当对象中还存在复杂数据类型的时候,只会拷贝地址引用,所以新对象对其修改值的时候,还会影响原来的对象中的值;

三种方式可以实现:

方式一:使用循环遍历对象,将其键值赋值给一个新数组;

// 对象的浅拷贝
var obj = {
    name: '张三',
    age: 33,
    sex: '男',
    hobby: {
        a: '1'
    }
}

var newObj = {}; 

//  循环遍历数组
for (var k in obj) {
    newObj[k] = obj[k];
}

console.log(newObj);    //{name: "张三", age: 33, sex: "男", hobby: {…}} 


newObj.hobby.a = '2';
console.log(obj.hobby.a);    // 2
console.log(newObj.hobby.a); // 2

方式二:采用Object.assign(新数组,拷贝的数组);方法

// 对象的浅拷贝
var obj = {
    name: '张三',
    age: 33,
    sex: '男',
    hobby: {
        a: '1'
    }
}

var newObj = {};
Object.assign(newObj, obj); 

console.log(newObj);    // {name: "张三", age: 33, sex: "男", hobby: {…}}

newObj.hobby.a = '2';
console.log(obj.hobby.a);    //2
console.log(newObj.hobby.a);    //2

方式三:使用jQuery中的$.extend();方法

var obj = {
    name: '张三',
    age: 33,
    sex: '男',
    hobby: {
        a: '1'
    }
}

var newObj = {}; 
$.extend(newObj, obj);     //将obj复制到新对象中

console.log(newObj);    //{name: "张三", age: 33, sex: "男", hobby: {…}} 

newObj.hobby.a = '2';
console.log(obj.hobby.a);    //2
console.log(newObj.hobby.a);    //2

 

 

二、深拷贝

就为了避免拷贝数据之后,引用数据类型之间的相互影响,我们需要深拷贝数据,将引用数据的值拷贝,而不再拷贝其地址;

也有三种方式可以实现;

方式一:使用递归循环拷贝对象;

利用 instanceof 对每一项数据进行类型判断,是否是数组类型,是否是对象类型;如果是,在此基础上,再进行循环;不是 就赋值;

// 对象的浅拷贝
var obj = {
    name: '张三',
    age: 33,
    sex: '男',
    hobby: {
        a: '1'
    }
}

var newObj = {}; 

//递归循环  
function deepCopy(newObj, oldObj) {
    for (var k in oldObj) {
        if (oldObj[k] instanceof Array) {
            newObj[k] = [];
            deepCopy(newObj[k], oldObj[k]);
        }
        else if (obj[k] instanceof Object) {
            newObj[k] = {};
            deepCopy(newObj[k], oldObj[k]);
        } else {
            // 基本数据类型
            newObj[k] = oldObj[k];
        }
    }
}

// 对象深拷贝
deepCopy(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

浅拷贝+递归:解决下面的那种方式JSON.parse(JSON.stringify(obj))不能拷贝对象中的方法;而且使用Object.prototype.toString.call(obj)可以准确判断数据的具体类型,不会有偏差,推荐使用;

//浅拷贝+递归:解决JSON.parse(JSON.stringify(obj))不能拷贝对象中的方法
function deepCopy(obj) {
    if (Object.prototype.toString.call(obj).slice(8, -1) == 'Object') {
        var result = {}
    } else if (Object.prototype.toString.call(obj).slice(8, -1) == 'Array') {
        var result = []
    } //判断数据类型类型  

    for (var attr in obj) {
        if (typeof obj[attr] == 'object') {
            result[attr] = deepCopy(obj[attr])
        } else {
            result[attr] = obj[attr]
        }
    }
    return result
}

 

方式二:利用JSON.prase()和JSON.stringify()方法 实现对象的深拷贝;

弊端:这一种方式不能拷贝函数!!!

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 }

原理:现将对象转成字符串,然后将字符串转成对象;

// 对象的浅拷贝
var obj = {
    name: '张三',
    age: 33,
    sex: '男',
    hobby: {
        a: '1'
    }
}

var newObj = {};

var objStr = JSON.stringify(obj);
newObj = JSON.parse(objStr);

console.log(newObj);    //{name: "张三", age: 33, sex: "男", hobby: {…}} 

newObj.hobby.a = '2';
console.log(obj.hobby.a);    //1
console.log(newObj.hobby.a);    //2

方式三:利用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

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值