Javascript对象的深浅拷贝

简介: Javascript对象的深浅拷贝

image.png


开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。

其实都是copy。


深拷贝(递归复制,复制所有层级,独立副本,一个完全和原来对象属性无关的副本)

返回对象:一个。

传入对象:一个。


条件:JSON安全的对象,可以序列化为JSON字符串,并且可以解析为新的字符串。

深拷贝算法:

function deepCopy(data){
    let memory = null;
    const type = Object.prototype.toString.call(data);
    if (type === "[object Array]"){
        memory = []
        for (let i=0 ;i<data.length;i++){
            memory.push(deepCopy(data[i]))
        }
    }else if (type === "[object Object]"){
        memory = {}
        Object.keys[data].forEach((key)=>{
            memory[key] = data[key]
        })
    }else{
        return data;
    }
    return memory;
}


jQuery深拷贝:

var copiedObject = jQuery.extend(true, {}, originalObject)


es6深拷贝:

var copiedObject= JSON.parse(JSON.stringify(originalObject));

深拷贝是递归复制,新复制的对象与原对象是完全独立的两个对象,它们指向不同的内存地址,做set不会影响到对方。


image.png


浅拷贝(单次复制,复制最高层级,引用副本,一个基于对原对象属性引用的副本)

返回对象:一个。

传入对象:一个或多个。

条件:无。


jQuery浅拷贝:

var copiedObject = jQuery.extend({}, originalObject)


es6浅拷贝:

var copiedObject = Object.assign({},originalObject)


es7浅拷贝:

var copiedObject = {...originalObject}


浅拷贝算法:

  function shallowCopyObj(original){
        let copy = {}
        Object.keys(original).forEach(key=>{
            copy[key] = original[key]
        })
        return copy
    }


由于javascript的对象是存地址的,所以浅复制的对象与原对象,都指向同一个内存地址,属于引用复制,做set会影响到对方


image.png


实验:


①普通属性修改:深拷贝和浅拷贝都可以满足对象的复制。


普通属性是指value值为非Array,Object类型的数据类型,也就是Number,String,Boolean等基本数据类型。

原因:基本数据类型属于值传递。

var obj = {foo:1};
var deepCopyObj = JSON.parse(JSON.stringify(obj));
deepCopyObj.foo = 2;
console.log("obj.foo:",obj.foo);//1
console.log("deepCopyObj.foo:",deepCopyObj.foo);//2
var obj = {foo:1};
var shallowCopyObj = Object.assign({},obj);
shallowCopyObj.foo = 2;
console.log("obj.foo:",obj.foo);//1
console.log("shallowCopyObj.foo:",shallowCopyObj.foo);//2

②高级属性修改:深拷贝满足对象的复制,浅拷贝影响原数组。

高级属性是指Array,Object数据类型。

原因:基本数据类型属于引用传递。

var obj = {foo:1,bar:{baz:1}};
var deepCopyObj = JSON.parse(JSON.stringify(obj));
deepCopyObj.bar.baz = 2;
console.log("obj.bar.baz:",obj.bar.baz);//1
console.log("deepCopyObj.bar.baz:",deepCopyObj.bar.baz);//2


var obj = {foo:1,bar:{baz:1}};
var shallowCopyObj = Object.assign({},obj);
shallowCopyObj.bar.baz = 2;
console.log("obj.bar.baz:",obj.bar.baz);//2 Attention!
console.log("shallowCopyObj.bar.baz:",shallowCopyObj.bar.baz);//2


印象中const也是保持变量地址不变的操作,那么es6中的let和const对于对象的深浅拷贝有影响吗?


也就是将上面代码中的var替换为let和const。


实验结果是let和const不会影响深浅拷贝的结果,因为let强调块作用域,而const强调变量整体地址空间的不变性。


关于对象的深浅拷贝,暂且探索到这里,后续有新发现再进行补充。


2021年5月30日更新

深拷贝(仅支持原始类型,Object和Array类型的深拷贝)

function copy(src){
    if(typeof src!=='object' || src === null) return src;
    let dest = {}
    if(Array.isArray(src)){
        dest = src.map((e)=>copy(e));
        return dest;
    }
    for(const [key, value] of Object.entries(src)){
        if(typeof value !== 'object'){
            dest[key] = value;
        } else if(Array.isArray(value)){
            dest[key] = value.map((e)=>copy(e))
        }else {
            dest[key] = copy(value)
        }
    }
    return dest
}



谢谢您的阅读~

相关文章
|
1月前
|
JavaScript 前端开发
JavaScript Date(日期) 对象
JavaScript Date(日期) 对象
37 2
|
3天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
3天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
27天前
|
存储 JavaScript 前端开发
JavaScript 对象的概念
JavaScript 对象的概念
34 4
|
25天前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
27 1
|
26天前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
15 2
|
29天前
|
JavaScript 前端开发 Unix
Node.js 全局对象
10月更文挑战第5天
20 2
|
1月前
|
存储 JavaScript 前端开发
js中的对象
js中的对象
18 3
|
1月前
|
JavaScript 前端开发
JavaScript Math(算数) 对象
JavaScript Math(算数) 对象
19 4
|
1月前
|
Web App开发 JavaScript 前端开发
JavaScript Window - 浏览器对象模型
JavaScript Window - 浏览器对象模型
21 2