前言:

在面试中,你必须要知道的一个知识点,那就是浅拷贝和深拷贝,那么就必须知道基本数据类型和引用类型,其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。

网片来自网络(侵删)

重点:你需要记住一句话:值类型传递的是值,引用类型传递的是地址

基本数据类型

这里就不做过多介绍了,基本数据类型值放在栈区,可直接访问与修改,且相互之间不会影响

引用类型

引用类型地址放在栈区,值放在堆区,所以当你进行赋值操作,其实赋值的是地址,所以二者之间是有关系的:

var obj1={name:'mengyun',age:18
};
var obj2 = obj1;
obj2.name = 'meimei';
console.log(obj1);//{name:'meimei',age:18}
console.log(obj2);//{name:'meimei',age:18}

可见是有联系的,而且曾经我一度以为赋值操作就是浅拷贝,其实不是的,还是太年轻~

下面看一个例子:

var obj1 = {name: 'mengyun',age: 18,hobby:{ play: [ 'footboll' ], read: 'book' },eat: ['苹果', '香蕉', '菠萝']
};var obj2 = obj1;function shallowCopy(target) {var result;if (Object.prototype.toString.call(target).slice(8, -1) === 'Object'){result={}}else if(Object.prototype.toString.call(target).slice(8, -1) === 'Array'){result=[]}for (var prop in target) {if (target.hasOwnProperty(prop)) {result[prop] = target[prop];}}return result;
}
var obj3 = shallowCopy(obj1);
obj2.name = "meimei";
obj3.age = "20";
obj2.hobby.play = ["games"];
obj3.hobby.read= ["news"];
obj3.eat = ['哈密瓜']; // 修改一层引用类型
console.log(obj1);
console.log(obj2);
console.log(obj3);

结果如图:

因为浅拷贝只复制一层对象的属性,并不包括对象里面的为引用类型的数据。所以就会出现改变浅拷贝得到的 obj3 中的引用类型时,会使原始数据得到改变。而且浅拷贝可以修改第一层的引用类型

浅拷贝:

拷贝就是复制,就相当于把一个对象中的所有的内容,复制一份给另一个对象,直接复制,或者说,就是把一个对象的地址给了另一个对象,他们指向相同,两个对象之间有共同的属性或者方法,都可以使用

实现浅拷贝的方法:

  1. 手写一个浅拷贝
function shallowCopy(target) {var result;if (Object.prototype.toString.call(target).slice(8, -1) === 'Object'){result={}}else if(Object.prototype.toString.call(target).slice(8, -1) === 'Array'){result=[]}for (var prop in target) {if (target.hasOwnProperty(prop)) {result[prop] = target[prop];}}return result;
}
  1. Object.assign()
var obj1 = {
name: 'mengyun',age: 18,hobby: { play: ['footboll'], read: 'book' },eat: ['苹果', '香蕉', '菠萝'],
};var obj2 = obj1;var obj3 = Object.assign({}, obj1);
obj2.name = "meimei";
obj3.age = "20";
obj2.hobby.play = ["games"];
obj3.hobby.read = ["news"];
obj3.eat = ['哈密瓜']; // 修改一层引用类型
console.log(obj1);
console.log(obj2);
console.log(obj3);

结果和上面一样

  1. 数组的浅拷贝
    展开运算符
var arr1=[1,2,3];
var arr2 = arr1;
arr2[1]='666';
console.log(arr1);//[1, "666", 3]
console.log(arr2);//[1, "666", 3]var arr3 = [5,6,7];
var arr4 = [...arr3];
arr4[1]='666';
console.log(arr3);//[5,6,7]
console.log(arr4);//[5, "666", 7]

concat():

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]

深拷贝:

把一个对象中所有的属性或者方法,一个一个的找到,并且在另一个对象中开辟相应的空间,一个一个的存储到另一个对象中

实现深拷贝的方法:

  1. JSON.parse(JSON.stringify())
let obj1 = {a:3,b:4
}let str = JSON.stringify(obj1);
let obj2 = JSON.parse(str);
obj2.a = 5;
console.log(obj1);  //{a: 3, b: 4}
console.log(obj2);  //{a: 5, b: 4}
  1. 手写一个深拷贝(递归)
    法1:
function deepClone(target) {var result;if (Object.prototype.toString.call(target).slice(8, -1) === 'Object') {result = {}} else if (Object.prototype.toString.call(target).slice(8, -1) === 'Array') {result = []}else{return target}for (var prop in target) {if (target.hasOwnProperty(prop)) {result[prop] = deepClone(target[prop]);}}return result;
}

法2:

function deepClone(target) {if(typeof target !=='object' || target==null){//target是null,或者不是数组、对象,直接返回return target}let result;//初始化结果if(target instanceof Array){result = []}else{result = {}}for (var prop in target) {if(target.hasOwnProperty(prop)){//保证key不是原型上的属性result[prop] = deepClone(target[prop]);}}return result;
}

测试案例:

var obj1 = {name: 'mengyun',age: 18,hobby: { play: ['footboll'], read: 'book' },eat: ['苹果', '香蕉', '菠萝'],
};var obj2 = obj1;var obj3 = deepClone(obj1);
obj2.name = "meimei";
obj3.age = "20";
obj2.hobby.play = ["games"];
obj3.hobby.read = ["news"];
obj3.eat = ['哈密瓜']; // 修改一层引用类型
console.log(obj1);
console.log(obj2);
console.log(obj3);

结果:

最后:

记住这张图

(图片侵删)

区别:

浅拷贝只复制对象的第一层属性、深拷贝可以对对象的属性进行递归复制

深拷贝和浅拷贝的区别(必须掌握)相关推荐

  1. Python基础:对象的深拷贝和浅拷贝的区别

    Python基础:对象的深拷贝和浅拷贝的区别 1 变量与对象 2 不可变对象与可变对象 3 直接赋值 4 浅拷贝 5 深拷贝 参考文献 1 变量与对象 对象:内存中存储数据的实体,有明确的类型.在Py ...

  2. python 深拷贝_详解python的复制,深拷贝和浅拷贝的区别

    概述 今天主要来看看Python中的浅拷贝和深拷贝内容,这里用一个实例来说明~ 需求: 将一个列表的数据复制到另一个列表中. 思路: 使用列表[:],拿不准可以调用copy模块. 实现方法: #!/u ...

  3. c++深拷贝和浅拷贝的区别?

    c++深拷贝和浅拷贝的区别 浅拷贝 深拷贝 总结 浅拷贝 对一个已知对象进行拷贝,编译系统会自动调用一种构造函数--拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数,调用一次构造函数 ...

  4. Python中深拷贝与浅拷贝的区别?

    往期面试题: 列举Python中的标准异常类? 说说Python面向对象三大特性? 说说Python中有几种数据类型? 说说Python模块主要分哪三类? 废话不多说,开始今天的题目: 问:说说Pyt ...

  5. python的复制,深拷贝和浅拷贝的区别

    python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有 ...

  6. C++深拷贝与浅拷贝的区别-简单易懂

    C++深拷贝与浅拷贝的区别-简单易懂 介绍 浅拷贝就比如像引用类型,而深拷贝就比如值类型. 浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同).对其中任何一个对象的改动都会影响另 ...

  7. python中深拷贝与浅拷贝的区别

    ####################python中的数据类型####################### ##########python中的数据类型有6种,分别为:数字类型如int,float ...

  8. 【C++面试问答】搞清楚深拷贝与浅拷贝的区别

    问题 深拷贝和浅拷贝的区别是面试中的常见问题之一,对于不同的编程语言,这个问题的回答可能稍有差别,下面我们就来探索一下它们之间的异同吧. 先来看看在JavaScript对象的深拷贝与浅拷贝的区别: 浅 ...

  9. 如何完美解答面试问题——深拷贝和浅拷贝的区别

    大家好,我是孤焰.今天要谈一谈在面试过程中可能被面试官提到的一个问题--深拷贝和浅拷贝的区别? 由于我也是刚刚学习编程的小白,所以此篇博文将参考了多篇博文,最后总结而成. 最近由于多门考试临近,所以博 ...

  10. java -- 深拷贝和浅拷贝的区别 如何实现深拷贝和浅拷贝

    文章目录 1. 深拷贝和浅拷贝的区别 1.1 浅拷贝实例 1.1.1 测试1 直接赋值 1.1.2 测试2 改变源对象的值 1.2 深拷贝实例 `这是用于深拷贝的测试类` 1.2.1 方法一: 构造函 ...

最新文章

  1. JavaScript学习笔记—— 4. 变量、作用域和内存问题
  2. 万能头文件#include<bits/stdc++.h>更新GCC10.2.0版本
  3. 数组-0~n-1 中缺失的数(查找不存在的数)
  4. 338. Counting Bits
  5. (转)Web Framework 的速度与激情 16 正式上映
  6. 人工智能AI实战100讲(十)-一文读懂推荐系统负采样
  7. php域名墙检测,php 网站域名被墙判断请求方法
  8. ubuntu11中卸载gnome3
  9. 南阳理工ACM 题目252 01串
  10. inside MPQ
  11. 医用计算机考试题目,2015年全国计算机应医用能力考试辅导资料.doc
  12. 漫步数理统计三十四——顺序统计量
  13. android数字滚动控件,Ticker 滚动数字控件
  14. 蓝桥杯2013年第四届C++B组省赛真题
  15. 完美解决移动端video视频层级问题
  16. 矩阵的求秩:rank( )
  17. html input onfocus
  18. Windows进程通信之剪贴板
  19. 微信|公众平台开发者文档
  20. 第57期、养老院信息管理系统

热门文章

  1. QT 插入视频并实现循环播放
  2. 电脑重装系统后播放视频卡顿怎么办
  3. spilt()分割字符串返回列表
  4. java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
  5. 用C语言:由键盘输入一个点的坐标,要求编程判断该点是否在单位圆上,如果在单位圆上则输出Y,不在单位圆上则输出N。使用小数点后3位精度进行判断。
  6. PaaS、IaaS 、SaaS、Bass、Fass、无服务的理解与区别
  7. php的chunk_split,php函数chunk_split详解
  8. workman与php通信
  9. 想当然很可怕,根子还是思考上的懒惰
  10. Step05:爬虫小项目,爬取最新电影迅雷下载地址