原文链接:http://www.cnblogs.com/chengguanhui/p/4737413.html

1、栈(stack)堆(heap)

  stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。       

2、基本类型和引用类型

  基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。

  5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。

  引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

  当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

3、传值与传址

  前面之所以要说明什么是内存中的堆、栈以及变量类型,实际上是为下文服务的,就是为了更好的理解什么是“浅拷贝”和“深拷贝”。

  基本类型与引用类型最大的区别实际就是传值与传址的区别。测试用例:

 1     var a = [1,2,3,4,5];2     var b = a;3     var c = a[0];4     alert(b);//1,2,3,4,55     alert(c);//16     //改变数值        7     b[4] = 6;8     c = 7;9     alert(a[4]);//6
10     alert(a[0]);//1

  从上面我们可以得知,当我改变b中的数据时,a中数据也发生了变化;但是当我改变c的数据值时,a却没有发生改变。

  这就是传值与传址的区别。因为a是数组,属于引用类型,所以它赋予给b的时候传的是栈中的地址(相当于新建了一个不同名“指针”),而不是堆内存中的对象。而c仅仅是从a堆内存中获取的一个数据值,并保存在栈中。所以b修改的时候,会根据地址回到a堆中修改,c则直接在栈中修改,并且不能指向a堆内存中。

3、浅拷贝

  前面已经提到,在定义一个对象或数组时,变量存放的往往只是一个地址。当我们使用对象拷贝时,如果属性是对象或数组时,这时候我们传递的也只是一个地址。因此子对象在访问该属性时,会根据地址回溯到父对象指向的堆内存中,即父子对象发生了关联,两者的属性值会指向同一内存空间。

 1   var a = {2         key1:"11111"3     }4     function Copy(p) {5         var c = {};6         for (var i in p) { 7           c[i] = p[i];8         }9         return c;
10   }
11     a.key2 = ['小辉','小辉'];
12     var b = Copy(a);
13    b.key3 = '33333';
14     alert(b.key1);     //1111111
15     alert(b.key3);    //33333
16     alert(a.key3);    //undefined

  a对象中key1属性是字符串,key2属性是数组。a拷贝到b,12属性均顺利拷贝。给b对象新增一个字符串类型的属性key3时,b能正常修改,而a中无定义。说明子对象的key3(基本类型)并没有关联到父对象中,所以undefined。

1 b.key2.push("大辉");
2 alert(b.key2);    //小辉,小辉,大辉
3 alert(a.key2);    //小辉,小辉,大辉

  但是,若修改的属性变为对象或数组时,那么父子对象之间就会发生关联。从以上弹出结果可知,我对b对象进行修改,a、b的key2属性值(数组)均发生了改变。其在内存的状态,可以用下图来表示。

  原因是key1的值属于基本类型,所以拷贝的时候传递的就是该数据段;但是key2的值是堆内存中的对象,所以key2在拷贝的时候传递的是指向key2对象的地址,无论复制多少个key2,其值始终是指向父对象的key2对象的内存空间。

4、深拷贝

  或许以上并不是我们在实际编码中想要的结果,我们不希望父子对象之间产生关联,那么这时候可以用到深拷贝。既然属性值类型是数组和或象时只会传址,那么我们就用递归来解决这个问题,把父对象中所有属于对象的属性类型都遍历赋给子对象即可。测试代码如下:

 1   function Copy(p, c) {2         var c = c || {};3         for (var i in p) {4           if (typeof p[i] === 'object') {5              c[i] = (p[i].constructor === Array) ? [] : {};6              Copy(p[i], c[i]);7           } else {8              c[i] = p[i];9           }
10         }
11         return c;
12   }
13     a.key2 = ['小辉','小辉'];
14     var b={};
15     b = Copy(a,b);
16     b.key2.push("大辉");
17     alert(b.key2);    //小辉,小辉,大辉
18     alert(a.key2);    //小辉,小辉

  由上可知,修改b的key2数组时,没有使a父对象中的key2数组新增一个值,即子对象没有影响到父对象a中的key2。其存储模式大致如下:

转载于:https://www.cnblogs.com/gavinyyb/p/6393183.html

js的浅拷贝与深拷贝相关推荐

  1. js之浅拷贝和深拷贝

    js数据类型主要分基本数据类型和引用数据类型.前者包括Number,String等,后者主要是Object,因此以下会针对不同的数据类型来分析,需要的朋友可以参考一下 1.js内存 js内存,或者说大 ...

  2. 【js】浅拷贝与深拷贝

    一.理解 1.浅拷贝:只是拷贝一层,更深层次对象级别的只拷贝了地址. 浅拷贝的时候如果数据是基本数据类型,那么就如同直接赋值那种,会拷贝其本身,如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言 ...

  3. js实现浅拷贝和深拷贝

    一.数据类型 数据分为基本数据类型和引用数据类型 基本数据类型(String, Number, Boolean, Null, Undefined,Symbol) 引用数据类型(Object[Array ...

  4. 小tips:JS之浅拷贝与深拷贝

    浅拷贝: function extendCopy(p) {var c = {};for (var i in p) {c[i] = p[i];}return c; } 深拷贝: function dee ...

  5. js 对象浅拷贝和深拷贝

    var model={name:"boy",age:13}; var CopyModel=model; console.log(CopyModel.name); model.nam ...

  6. JS中浅拷贝和深拷贝的使用,深拷贝实现方法总结

    1.浅拷贝:两个对象经过拷贝后虽然具有相同的属性,但是他们都指向同一个内存空间.操作会引起引用,同一地址的变量一起改变. let a = {x: 1} let b = a b.x = 2 consol ...

  7. js对象浅拷贝与深拷贝

    一.简介    浅拷贝是拷贝一层,如果数据是基本数据类型,会拷贝其本身,如果除了基本数据类型之外还有一层对象,那么只能拷贝其引用,对象的改变会反应到拷贝对象上.    深拷贝是拷贝多层,每一层的数据都 ...

  8. js关于浅拷贝、深拷贝,数组的深拷贝

  9. 说说JS中的浅拷贝与深拷贝

    outline: 为什么要说JS中深拷贝与浅拷贝 JS对类型的分类 immutable与mutable 简单类型检测 浅拷贝VS深拷贝 为什么要说JS中深拷贝与浅拷贝 近来在研读underscore的 ...

  10. js 浅拷贝直接赋值_JS中实现浅拷贝和深拷贝的代码详解

    (一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. ...

最新文章

  1. 百度正在摆脱广告营收依赖!AI云增长64%成最大推动力
  2. ISLR学习笔记(2)线性回归
  3. .NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练
  4. Wrapper+map实现页面显示
  5. 云小课 | 华为云KYON之VPC终端节点
  6. 《天天数学》连载28:一月二十八日
  7. JavaScript模块化思想
  8. android小项目数字拼图游戏_Java小项目之:拼图游戏
  9. HTML !DOCTYPE 声明详解
  10. qq批量登录软件_QQ账号永久冻结
  11. div中img居中显示
  12. 米斯齐超声波传感器显示测量距离(oled)内附Arduino代码
  13. nRF24L01 无线数传模块之间的区别 干货分析
  14. php access 会员管理,Member access operators(会员接入运营商)
  15. Python版本极简打飞机
  16. nofollow标签使用方法
  17. 【WY】数据分析 — 空间数据阶段一 :进阶语法 二 —— 3D图表
  18. 用C# ASP.NET MVC 实现WebSocket
  19. Redis主从复制详解(入门教程)
  20. pycharm初体验

热门文章

  1. gitee图床失效后处理
  2. c#modbus tcp通讯助手开源_Modbus 调试助手的使用(一)
  3. 【渝粤教育】国家开放大学2018年秋季 0179-21T数据库基础与应用 参考试题
  4. 【渝粤教育】国家开放大学2018年秋季 1302T护理科研方法 参考试题
  5. 【渝粤教育】国家开放大学2018年秋季 0714-21T建筑识图与CAD 参考试题
  6. 【渝粤教育】国家开放大学2018年春季 0054-22T合同法 参考试题
  7. 【渝粤教育】电大中专电商运营实操 (7)作业 题库
  8. SQL Server和Oracle数据库索引介绍
  9. c语言名著摘抄——语法及实例
  10. SA / SAM 题目集