深拷贝和浅拷贝是在面试中经常遇到的问题。今天在这里总结一下。

深拷贝与浅拷贝的问题,涉及到JavaScript的变量类型,先来说说变量的类型,变量类型包括基本类型和引用类型。

  • 基本类型:Undefined,Null,Boolean,String,Number
  • 引用类型:Array,Object,Date,RegExp,Function等

    基本类型的变量直接按值存放在栈区里面,可以直接访问,比如我们平时把字符串、数字的值赋值给新变量,就是把值完全赋值过去,新变量的改变不会影响旧变量。

    引用类型是存放在堆区的对象,变量在栈区中保存的是一个指针地址,指向真正保存在堆区中的对象。

浅拷贝

1.定义:浅复制只复制一层对象的属性。

  • 针对对象中的基本类型是新开辟一块内存进行存储,改变新对象中的基本类型值不会影响原对象。
  • 而对于对象中的引用类型,也会新开辟一块内存,不过这块内存,仅仅是用来存储对象中的引用类型的地址(即指针,这个指针还是指向存储在堆内存中的原对象)

    先来看一段代码:下面这段代码只是浅复制
var obj = {
a:1,
arr: [2,3]
};
var shallowObj = shallowCopy(obj);
function shallowCopy(src){
var dst = {};
for(var prop in src){
if(src.hasOwnProperty(prop)){
dst[prop] = src[prop];
}
}
return dst;
}
console.log(shallowObj.a);//1
shallowObj.a = 3;
console.log(shallowObj.a);//3
console.log(obj.a);//1
console.log(shallowObj.arr);//[2,3]
shallowObj.arr[0] = 3;
console.log(shallowObj.arr);//[3,3]
console.log(obj.arr);//[3,3]

2.实现方式

  • 可以通过es6新增的Object.assign来复制对象
let obj = {
name: "xiaoming",
hobby: [
"pinpong",
"soccer"
]
}; let copyObj = Object.assign({},obj);
copyObj.name = "xiaohong",
copyObj.hobby[0] = "jianzi";
console.log(obj);
console.log(copyObj);

  • jQuery中的$.extend(,obj);Array.prototype.slice()和Array.prototype.concat()都会返回一个数组或者对象的浅拷贝。

深拷贝

1.定义:深拷贝不仅会将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,这就不会存在上图中的obj和shallowObj的arr属性指向同一个对象的问题。

function cloneDeep(obj){
if(typeof obj !== 'object' || Object.keys(obj).length === 0 ){
return obj;
}
let resultData = {};
return recurison(obj, resultData);
} function recurison(obj, data = {}){
for(key in obj){
if(typeof obj[key] == 'object' && Object.keys(obj[key].length > 0 )){
data[key] = recurison(obj[key]);
}else{
data[key] = obj[key];
}
}
return data;
} var o1 = {
arr: [1, 2, 3],
obj: {
key: 'value'
},
func: function(){
return 1;
}
}; var o3 = cloneDeep(o1);
console.log(o3 === o1);//false
console.log(o3.obj === 01.obj);//false
console.log(o3.func === o1.func);//true

深拷贝对基本类型和引用类型都会新开辟一块内存来存储它们,需要注意的是,如果对象比较大,层级比较多,深复制会带来性能上的问题。所以在遇到深复制的情况时,可以考虑有没有其他替代的方案。在实际的应用场景中,也是浅复制更为常用。

2.JSON对象中的parse和stringify,JSON对象中的stringify可以把一个js对象序列化为一个JSON字符串,parse可以将JSON字符串反序列化为一个js对象,通过这两个方法,也可以实现对对象的深复制。

JavaScript的深拷贝与浅拷贝的更多相关文章

  1. javascript对象深拷贝,浅拷贝 ,支持数组

    javascript对象深拷贝,浅拷贝 ,支持数组 经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One meth ...

  2. 也来玩玩 javascript对象深拷贝,浅拷贝

    经常看到讨论c#深拷贝,浅拷贝的博客,最近js写的比较多, 所以也来玩玩js的对象拷贝. 下面是维基百科对深浅拷贝的解释: 浅拷贝 One method of copying an object is ...

  3. JavaScript的深拷贝和浅拷贝总结

    深拷贝和浅拷贝 深拷贝:拷贝实例:浅拷贝:拷贝引用(原对象). 说深拷贝和浅拷贝之前,我先去了解了下高程书上的JavaScript的变量类型: 基本类型:undefined.null.Boolean. ...

  4. JavaScript的深拷贝和浅拷贝

    一.数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型.. 1.基本数据类型的特点:直接存储在栈(stack ...

  5. 详解javascript的深拷贝与浅拷贝

    1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...

  6. JavaScript 的 深拷贝和浅拷贝

    深拷贝和浅拷贝都是针对的引用类型, JS中的变量类型分为值类型(基本类型)和引用类型: 对值类型进行复制操作会对值进行一份拷贝,而对引用类型赋值,则会对地址进行拷贝,最终两个变量指向同一份数据 一.先 ...

  7. JavaScript之深拷贝和浅拷贝

    前言 工作中会经常遇到操作数组.对象的情况,你肯定会将原数组.对象进行‘备份’当真正对其操作时发现备份的也发生改变,此时你一脸懵逼,到时是为啥,不是已经备份了么,怎么备份的数组.对象也会发生变化.如果 ...

  8. javaScript深拷贝和浅拷贝简单梳理

    在了解深拷贝和浅拷贝之前,我们先梳理一下: JavaScript中,分为基本数据类型(原始值)和复杂类型(对象),同时它们各自的数据类型细分下又有好几种数据类型 基本数据类型 数字Number 字符串 ...

  9. 读懂javascript深拷贝与浅拷贝

    1. 认识深拷贝和浅拷贝 javascript中一般有按值传递和按引用传递两种复制,按值传递的是基本数据类型(Number,String,Boolean,Null,Undefined),一般存放于内存 ...

随机推荐

  1. Python第三方库matplotlib(2D绘图库)入门与进阶

    Matplotlib 一 简介: 二 相关文档: 三 入门与进阶案例 1- 简单图形绘制 2- figure的简单使用 3- 设置坐标轴 4- 设置legend图例 5- 添加注解和绘制点以及在图形上 ...

  2. Exception 和 Error 包结构

  3. Java GC策略

    本文转自https://blog.csdn.net/rabbit_in_android/article/details/50386954 内存管理和垃圾回收 JVM内存组成结构 JVM栈由堆.栈.本地 ...

  4. Oracle 内存管理

    --内存分配建库时可以先分配系统内存的50%-80%给Oracle,后期根据业务再进行调整.SGA.PGA分配比例:OLTP:SGA %80 , PGA %20OLAP:SGA %50 , PGA % ...

  5. 12-5 NSSet

    原文:http://rypress.com/tutorials/objective-c/data-types/nsset NSSet NSSet, NSArray, and NSDictionary  ...

  6. Oracle简述

    Oracle是甲骨文公司推出的一款大型数据库管理系统.甲骨文公司成立于1977年,总部位于美国加利福尼亚州的红木滩.1989年,Oracle正式进入中国市场:2013年,甲骨文超越 IBM ,成为继 ...

  7. CentOS下配置FTP

    http://www.cnblogs.com/zhenmingliu/archive/2012/04/25/2470646.html 常见错误: 1.FTP服务器已经拒绝 解决方案 # setenfo ...

  8. vue-cli脚手架引入element UI的正确打开方式

    element UI官网教程:http://element-cn.eleme.io/#/zh-CN/component/quickstart 1.完整引入,直接了当,但是组件文件不是按需加载,造成多余 ...

  9. django使用JWT保存用户登录信息

    在使用前必须弄明白JWT的原理,原理可以看我的另一篇博文:https://www.cnblogs.com/chichung/p/9966027.html JWT的流程 1.签发JWT 在用户正确输入账 ...

  10. linux下不解包查看tar包文件内容

    为减少日志文件占用的空间,很多情况下我们会将日志文件以天或周为周期打包成tar.gz 包保存.虽然这样做有利空间充分利用,但当我们想查看压缩包内的内容时确很不方便.如果只是一个tar.gz文件,可以将 ...