资讯专栏INFORMATION COLUMN

Javascript系列之浅复制与深复制

MonoLog / 2350人阅读

摘要:定义浅复制如果复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。浅复制数组浅复制利用数组方法和返回新数组特性,进行复制。深复制对象深复制利用对象的和方法。

定义 浅复制

如果复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。

深复制

深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复制的对象的引用图不包含任何原有对象或对象图上的任何对象,复制后的对象与原来的对象是完全隔离的。

浅复制 数组浅复制

利用数组方法slice和concat返回新数组特性,进行复制。

var arr = [1,2,3];
var new_arr = arr.concat();
arr[0] = "new";
console.log(new_arr);      //[1, 2, 3]

再来看一组情况:

var arr = [{name: "haha"}, [1,2,3]];
var new_arr = arr.concat();
arr[0].name = "lily";
console.log(new_arr.name);      //"lily"

可以看出,如果数组元素是基本数据类型,就会复制一份,互不影响,而如果是对象或者数组,就会只复制对象和数组的引用。

扩展运算符
var obj = { name: "jack" };
var a = [1, 2];
var b = [3, obj];
a.push(...b);
a   // [1, 2, 3, {name: "jack"}]
a[3].name = "rose";
b   // [3, {name: "rose"}]
Object.assign
var obj = { name: "jack" };
var copyObj = Object.assign({}, obj);
obj.name = "rose";
copyObj   // {name: "rose"}
自定义浅复制
function shallowCopy(obj) {
    if (typeof obj !== "object") return;
    var new_obj = obj instanceof Array ? [] : {};

    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = shallowCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"lily"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"5,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }

由此可以看出,此方法确实可以复制object和array对象,但无法进行深复制;但是可以复制function。

深复制 对象深复制

利用JSON对象的parse和stringify方法。

var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = JSON.parse(JSON.stringify(source));
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr:[1,2,34] }
source.child.name = "lily";
console.log(target.name);              //"child"
source.arr[0] = 5;
console.log(target.arr);              //"1,2,34"

由此可以看出,虽然此方法确实可以复制object和array对象,并且进行了深复制,却无法复制function。

自定义深复制
function deepCopy(obj) {
    if (typeof obj !== "object") return;
    var new_obj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            new_obj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key];
        }
    }
    return new_obj;
}
var source = {
    name: "source",
    child: {
        name:"child"
    },
    arr: [1,2,34],
    setName: function() { 
        this.name = "haha"; 
    }
};
var target = deepCopy(source);
console.log(target);              //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function }
source.child.name = "lily";
console.log(target.child.name);              //"child"
source.name = "sam";
console.log(target.name);                   //"source"
source.arr[0] = 5;
console.log(target.arr);                   //"1,2,34"
source.setName = function() { console.log(this.name); };
console.log(target.setName );            //function(){ this.name = "haha";  }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89343.html

相关文章

  • JS系列之目录

    摘要:设计模式资源整理操作符小知识点实现发邮件功能数据结构与算法资源整理跨域函数的合成与柯里化系列之防抖节流系列之正则系列之系列之系列之编码系列之系列之操作符对象中的坐标检测对象或数组系列之机制系列之构造对象系列之总结系列之浅复制与深复制系列之对 Javascript设计模式资源整理JS操作符JS小知识点JS实现发邮件功能数据结构与算法资源整理跨域函数的合成与柯里化JS系列之防抖节流JS系列...

    AaronYuan 评论0 收藏0
  • 小tips:JS之浅拷贝与深拷贝

    摘要:浅拷贝深拷贝浅拷贝的问题如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。 浅拷贝: function extendCopy(p) {  var c = {};  for (var i in p) {    c[i] = p[i];  }  return c; } 深拷贝: function deepCopy(p...

    Soarkey 评论0 收藏0
  • JavaScript之浅、深拷贝

    摘要:前言里面浅拷贝和深拷贝是非常关键的知识点,今天就来通过本文清楚的了解深浅拷贝以及该如何实现这两种拷贝方式。对象的拷贝又分为浅拷贝和深拷贝。印证了上述所说的对于所有的基本类型,简单的赋值已经是实现了深拷贝。 前言 JavaScript里面浅拷贝和深拷贝是非常关键的知识点,今天就来通过本文清楚的了解深浅拷贝以及该如何实现这两种拷贝方式。 深浅拷贝的区别 拷贝:其实就是一个对象复制给另外...

    leanxi 评论0 收藏0
  • JavaScript 数据结构与算法之美 - 栈内存与堆内存 、浅拷贝与深拷贝

    摘要:栈内存与堆内存浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然。栈内存与堆内存中的变量分为基本类型和引用类型。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 前言 想写好前端,先练好内功。 栈内存与堆内存 、浅拷贝与深拷贝,可以说是前端程序员的内功,要知其然,知其所以然。 笔者写的 JavaScrip...

    dailybird 评论0 收藏0
  • JavaScript中的浅拷贝与深拷贝

    摘要:所以,深拷贝是对对象以及对象的所有子对象进行拷贝实现方式就是递归调用浅拷贝对于深拷贝的对象,改变源对象不会对得到的对象有影响。 为什么会有浅拷贝与深拷贝什么是浅拷贝与深拷贝如何实现浅拷贝与深拷贝好了,问题出来了,那么下面就让我们带着这几个问题去探究一下吧! 如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过 以下↓ 数据类型在开始了解 浅拷贝 与 深拷贝 之前,让我们先...

    546669204 评论0 收藏0

发表评论

0条评论

MonoLog

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<