JavaScript 浅拷贝与深拷贝

发布于 2023-05-09 13:19:41 字数 1801 浏览 46 评论 0

深浅拷贝区别

深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象(引用类型)的。

复制引用(引用类型)的拷贝方法称之为浅拷贝,也因为直接复制引用类型,导致新旧对象共用一块内存地址,会互相影响,具体看例子

深拷贝就是指完全的拷贝一个对象,将原对象的各个属性递归复制下来。这样即使嵌套了对象,两者也相互分离。

浅拷贝

var shallowCopy = function(obj) {
    if (typeof obj !== 'object') return;      // 只拷贝对象
    var newObj = obj instanceof Array ? [] : {};     // 根据obj的类型判断是新建一个数组还是对象
    for (var key in obj) {      // 遍历obj,并且判断是obj的属性才拷贝
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1])  // 5
shallowObj.a = 5;
console.log(obj.a) // 1 

备注:

①hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性。Object.prototype.hasOwnProperty();
②instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。

原理

遍历对象,然后把属性和属性值都放在一个新的对象

具体:判断是参数否为对象,是数组还是object;用 for in 遍历所传的参数对象,并用 if (arg.hasOwnProperty(prop)) 忽略掉继承属性,然后赋值给临时创建的对象,最后返回此对象。

深拷贝

实现一个深拷贝在拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数就OK了

var deepCopy = function(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1])  // 3
shallowObj.a = 5;
console.log(obj.a) // 1 

性能问题

尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

故笙诉离歌

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

eins

文章 0 评论 0

世界等同你

文章 0 评论 0

毒初莱肆砂笔

文章 0 评论 0

初雪

文章 0 评论 0

miao

文章 0 评论 0

qq_zQQHIW

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文