好记性不如烂笔头。记在脑子里不如做点笔记。

什么是深浅拷贝?

在理解这个问题之前,我们要先去了解一下js的数据类型,js数据类型分为基本数据类型和引用数据类型。

基本数据类型:string,number,null,undefined,boolean
引用数据类型:object对象(array,function,date,reg)

我们知道了js的数据类型,现在就可以来了解什么是深浅拷贝,先看基本数据类型的拷贝,代码如下:

var a = 2;  // 定义a变量赋值为2
var b = a;  // 把a变量赋值给b
a = 1;     // 修改a的值
console.log(a, b); // 1, 2

由上可以看出,a的值改变之后,b的值并没有跟着改变,再来看看引用类型的拷贝,代码如下:

var a = [1, 2, 3, 4];
var b = a;
a[1] = 0;
console.log(a, b);

结果:
操作和基本数据类型一样,b会跟着a改变,为什么会出现这样的情况呢?因为基本数据类型保存在栈内存里,而引用数据类型保存在堆内存里,保存在栈内存的必须是大小固定的数据,引用类型的大小不固定,只能保存在堆内存中,而我们定义的变量实际保存的是一个指针,这个指针指向的是堆内存。

代码解析:
1.基本数据类型拷贝:
当var a = 2的时候在栈内存中新开辟了一个空间保存a变量值为2,进行var b = a的时候是在内存中又开辟了新的空间保存着b,所以a和b两个变量互不相关。
2.引用数据类型拷贝:
进行var a = [1,2,3,4]的时候,在栈内存中保存的只是一个指针也可以说是地址,这个指针指向的是堆内存的一个对象,堆内存中保存着这个对象,当var b = a的时候,我们进行了复制但是复制的只是栈内存中的指针,堆内存中的本身对象并没有被复制,所以a[1] = 0的时候,b也改变了,因为a和b指向的是同一个对象。这就是浅拷贝。

由上总结得出:基本数据类型的拷贝就是直接赋值的操作,而深浅拷贝相对应的就是引用数据类型。

浅拷贝

浅拷贝只是拷贝基本类型的数据,如果所拷贝的对象的属性等于数组或另一个对象那就是只拷贝了指针,而没有拷贝堆内存中存储内容的对象,只要这个对象所改变了,所有指向这个对象的变量的值都会改变。看代码:戳这里

var Nation = {  nation: '中国'
};
function extendCopy(p) {  var c = {};  for (var i in p) {    c[i] = p[i];  }  return c;
}
var Doctor = extendCopy(Nation);
Doctor.career = '医生';
Doctor.nation = '美国';
console.log(Doctor.nation); // 美国
console.log(Nation.nation); // 中国
console.log(Doctor.career); // 医生

好像看起来都没错,Doctor对象新增了career 属性,而Nation对象并没有career 属性,他们好像没有什么关联,如果我们给属性的值是一个对象呢?再来看看:

 // 封装一个浅拷贝函数:function simpleClone(initalObj) {    var obj = {};    for ( var i in initalObj) {obj[i] = initalObj[i];}    return obj;}// 定义一个多层次的对象var obj = {a: "hello",b:{a: "world",b: 21},c:["Bob", "Tom", "Jenny"],d:function() {alert("hello world");}}// 赋值obj对象var obj1 = simpleClone(obj);obj1.c = ['mm', "Tom", "Jenny"];   // 改变obj1中的c属性的值// 打印一下console.log('obj=>>>',obj);  //obj.c =>  ["Bob", "Tom", "Jenny"]console.log('obj1=>>>',obj1);  //obj.c => ["mm", "Tom", "Jenny"]// 再来改变数组中的第一个元素  把上面的赋值和打印注释一下obj1.c[0] = 'bb'; // 浅拷贝时,改变属性的属性值,改变原对象// 再打印一下console.log('obj=>>>',obj); //obj.c => ["bb", "Tom", "Jenny"]console.log('obj1=>>>',obj1);  //obj.c => ["bb", "Tom", "Jenny"]

哦豁 完蛋, obj1.c[0] = 'bb’执行这一步的时候两个对象都改变了,为啥执行obj1.c = [‘mm’, “Tom”, “Jenny”]的时候两个对象没有关联,因为浅拷贝是只拷贝一层,把 obj1.c作为一个整体改变了,而obj1.c[0] = 'bb’深层次的对象的改变就需要用到深拷贝了。
另外:Object.assign()也能实现浅拷贝。

深拷贝

深拷贝的实现方式有很多种

  1. 最简单的json方法
    JSON.parse(JSON.stringify(obj))
  2. 使用Object.create()方法
function deepClone(initalObj, finalObj) {    var obj = finalObj || {};    for (var i in initalObj) {        var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况if(prop === obj) {            continue;}        if (typeof prop === 'object') {obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);} else {obj[i] = prop;}}    return obj;
}
  1. 递归
function deepClone(initalObj, finalObj) {    var obj = finalObj || {};    for (var i in initalObj) {        var prop = initalObj[i];        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况if(prop === obj) {            continue;}        if (typeof prop === 'object') {obj[i] = (prop.constructor === Array) ? [] : {};            arguments.callee(prop, obj[i]);} else {obj[i] = prop;}}    return obj;
}
var str = {};
var obj = { a: {a: "hello", b: 21} };
deepClone(obj, str);
console.log(str.a);

代码摘自:https://blog.csdn.net/weixin_37719279/article/details/81240658

js 深浅拷贝的整理相关推荐

  1. 9012年,当我们讨论js深浅拷贝时我们在说些什么?

    前言: 本文主要阅读对象:对深浅拷贝印象模糊对初级前端,想对js深浅拷贝聊一聊的中级前端.如果是对这些有完整对认知体系和解决方法的大佬,可以选择略过. 复制代码 正文: 讨论深浅拷贝,首先要从js的基 ...

  2. 实现JS深浅拷贝的五种方式

    一.堆栈.基本数据类型.引用数据类型 在了解深浅拷贝之前,我们需得对堆栈.基本数据类型.引用数据类型有基本的了解 基本数据类型:number.string.boolean.null.undefined ...

  3. 【学姐面试宝典】前端基础篇Ⅴ——JS深浅拷贝、箭头函数、事件监听等

    前言 博主主页

  4. JS中深浅拷贝 函数封装代码

    一.了解 基本数据类型保存在栈内存中,按值访问,引用数据类型保存在堆内存中,按址访问. 二.浅拷贝 浅拷贝只是复制了指向某个对象的指针,而不是复制对象本身,新旧对象其实是同一内存地址的数据,修改其中一 ...

  5. JS 中对象的深浅拷贝(ES3、ES5、ES6不同方法底层实现,一文搞清楚深浅拷贝面试常问题)

    JS 中对象的深浅拷贝   拷贝我们都知道这个词的意思,我们经常做过复制.粘贴的操作,其中的复制就是拷贝,那么在拷贝的时候,如果我们复制出来的内容和原内容是完全的分开,各自不相影响,那么这就属于深拷贝 ...

  6. php深浅拷贝,js实现深浅拷贝方法

    说起深浅拷贝,我觉得需要理清楚 值类型 和 引用类型,本文主要和大家分享js实现深浅拷贝方法,希望能帮助到大家. 值类型 所谓 值类型 就是 undefined,null,number, string ...

  7. 手写深浅拷贝(js)

    关于深浅拷贝的原理介绍可以看之前的文章--超清晰,一文理解深浅拷贝 浅拷贝和深拷贝的区别及实现: 浅拷贝:一般指的是把对象的第一层拷贝到一个新对象上去,比如 let a = { count: 0, i ...

  8. JS(JavaScript)中实现深浅拷贝的几种方式(详细阅读 非常重要)。

    在了解深浅拷贝之前,我们先一起来简单来了解一下,JavaScript 数据存储的方式,以及数据类型(). JavaScript 中数据存储分为 简单数据类型和复杂数据类型(引用数据类型) 其中 5 种 ...

  9. js中深浅拷贝理解与方法

    深浅拷贝的方法 堆栈理解 基本数据类型 number.string.boolean.null.undefined 引用数据类型 object.function.array 栈内存 存储基本数据类型内容 ...

  10. js递归函数及深浅拷贝

    <!DOCTYPE html> <html><head><meta charset="utf-8"><title>递归函 ...

最新文章

  1. php井字游戏,python实现井字棋游戏
  2. python将运行结果用窗口打开-如何打开新控制台并运行python脚本
  3. django之视图系统 views.py--主要内容(FBV和CBV、dispath、request对象和request.FILES、JsonResponse)...
  4. Openlayers中使用Overlay实现点击要素显示html内容弹窗并且动态更改弹窗内容
  5. 前后台分离之数据模拟
  6. VMware ubuntu 上网
  7. library的英语怎么读音_【英语角】———学习方法分享
  8. IEnumerable
  9. Linux学习之CentOS(五)----网卡的配置
  10. 【Elasticsearch】Meltdown对Elasticsearch性能的影响
  11. python 安装 setuptools Compression requires the (missing) zlib module 的解决方案
  12. jQuery lazyload
  13. 博为峰Java技术文章 ——JavaEE Hibernate HQL条件查询
  14. JZ3-从尾到头打印链表
  15. 如何在 Mac 上查找和管理 Safari 下载?
  16. Citrix 桌面云 XenApp_XenDesktop_7.15 部署系列(九)客户端使用
  17. KeyTool生成证书链及使用
  18. 激光锡焊在SMA连接器领域的应用
  19. 博弈论(五)——#10247. 「一本通 6.7 练习 4」S-Nim
  20. 令人啼笑皆非的不靠谱产品是如何诞生的?

热门文章

  1. CleanMyMac最新2020注册机
  2. Android源码 --- BroadCast源码分析
  3. matlab用imshow显示为纯白图像问题
  4. 分享Silverlight/WPF/Windows Phone一周学习导读(07月11日-07月17日)
  5. The remote device or resource won't accept the connect
  6. h5 android 重力 晃动,H5案例分享:html5重力感应事件(示例代码)
  7. 2013年台式计算机型号,2013cpu天梯图,台式机处理器天梯图
  8. delphi 10.3 (一) 控件安装和使用
  9. 调用微信支付api实现用户扫描二维码支付订单
  10. 【opencv-python】 HSV抠图-智能车拟合道路边界和中线