原文:深度解析javascript中的浅复制和深复制

在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型。我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型。而Object又包含Function,Array和Object自身。前面的五种类型叫做基本类型,而Object是引用类型。可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的。

我们首先来看看浅复制和深复制的简洁定义:

  • 深复制:直接将数据复制给对应的变量
  • 浅复制:将数据的地址复制给对应的变量

而数据类型和我们要讨论的复制类型又有怎样的联系呢?我们试着摸索一下吧

实验一:

 var a = "dengkunming";
var a1 = a;
alert(a1);//dengkunming
a="abc";
alert(a1);//dengkunming;

这段代码中我们把a赋值给a1,当a的值改变时,a1没有发生变化。

实验二:

 var a = [0,1,2,3];
var a1= a;
alert(a1);//[0,1,2,3]
a[1]="变";
alert(a1);//[0,"变",2,3]

在这段代码中我们同样把a赋值给a1,当a的值改变的时候,a1却发生了变化。

这是咋回事了,同样的操作其结果怎么会有差异了?我们回头看看,聪明的一休认为可能是这两个a有些不同。那些不同了?前面的是字符串,后面的数组。好像就是我们前面提到的基本类型和数据类型吧。那我们把数据类型换一下看看会有什么结果。

实验三:

 var a = 3578;
var a1 = a;
alert(a1);//
a=8735;
alert(a1);//

实验四:

 1 var a = {w1:2,w2:3}
2 var a1= a;
3 alert(a1);//{w1:2,w2:3}
4 a1.w1="邓";
5 alert(a);//{w1:"邓",w2:3}

在这两组实验中,我们把数据类型分别换成了Number型和Object类型。实验三中可以发现a1不随a值的变化而变化,实验四中a会随着a1的变化而变化(这里和实验二略有不同,改变的是a1,当然你改变a的话,a1也会跟着变化)

似乎我们可以得出个一般性的结论了:

    js中基本类型的赋值为深复制,而引用类型的赋值为浅复制。

   现在有必要把深复制和浅复制的定义扩展一下了。

  • 浅复制:就是把数据的地址赋值给对应变量,而没有把具体的数据复制给变量,变量会随数据值的变化而变化。
  • 深复制:就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。

实验五:

 var a = {w1:2,w2:3}
var a1= a;
alert(a1);//{w1:2,w2:3}
var a={x1:7,x2:8}
alert(a1);//{w1:2,w2:3}

按照我们上面的理论来讲,这里是浅复制。a1应该随着a的变化而变化呀,可在这里为什么会事与愿违了?这就是引用类型惹的祸了。对象赋值其实都是引用传值,传递的是一个地址。那么实验五中的第四行其实就是把变量a指向了一个新的地址。而a1还是指向的原来那个地址,原来地址中的值没变,所以a1就不会变。所以请记住:浅复制不会随着存储数据地址的变化而变化,只会随着数据值的变化而变化。

那我们如何实现引用类型的深度复制呢?这就是老话题深度克隆了。就是需要自己写一个非原生的clone函数喽。

 function clone(obj){
var o=[];
if(obj.constructor== Array) {
o=obj.slice(0);
}else{
o={};
for(var i in obj){
o[i] = typeof obj[i] === "object" ? obj[i].clone() : obj[i];}
}
return o; }

    小可不才,文章中定会有所纰漏,望指出。也学一下大牛的语气,此文原创,转载请注明出处。如果你觉得文章还不错,就怒顶并推荐一下下吧!!!!

深度解析javascript中的浅复制和深复制的更多相关文章

  1. 深度解析VC中的消息(转发)

    http://blog.csdn.net/chenlycly/article/details/7586067 这篇转发的文章总结的比较好,但是没有告诉我为什么ON_MESSAGE的返回值必须是LRES ...

  2. 深度解析javaScript常见数据类型检查校验

    前言 在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型 基础数据类型:数字Number 字符串String 布尔Boolean Null Un ...

  3. 深入解析Javascript中this关键字的使用

    深入解析Javascript中面向对象编程中的this关键字 在Javascript中this关键字代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如: function TestFun ...

  4. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  5. Java中引用的浅复制和深复制

    Java中除了基本类型int,char,double等的赋值是按照值传递之外,其余的类型和对象都是按照引用进行传递的. 下面来看一个关于引用的例子. package referenceCopy;// ...

  6. js中的浅复制和深复制

    浅复制:浅复制是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响 深复制:深复制不是简单的复制引用,而是在堆中重新分配内存,并且把源对象实例的所有属性都进行新建复制,以保证深复 ...

  7. 全面解析JavaScript中“&&”和“||”操作符(总结篇)

    1.||(逻辑或), 从字面上来说,只有前后都是false的时候才返回false,否则返回true. ? 1 2 3 4 alert(true||false); // true alert(false ...

  8. JAVA中浅复制与深复制

    1.浅复制与深复制概念⑴浅复制(浅克隆)被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵深复 ...

  9. Java中的“浅复制”与“深复制”

    复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...

随机推荐

  1. java设计模式演示示例

    创建一个模式 1.工厂方法模式(Factory Method)  该程序创建的操作对象,独自一人走出流程,创建产品工厂接口.实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相互 ...

  2. 高榕资本宾悦:未使用的企业家Testin云测试服务类故障

    高榕资本岳斌:创业者未使用Testin云測试服务属不合格 2014/10/09 · Testin · 开发人员訪谈 Testin云測与工信部等联合承办的ICT中国.2014高层论坛之移动开发人员分论坛 ...

  3. Java Enum使用演示样品枚举

    package cn.edu.shu.web.util; /** * * <p> * ClassName FileType * </p> * <p> * Descr ...

  4. GitLab一键式安装bitnami

    https://bitnami.com/stack/gitlab/installer https://bitnami.com/redirect/to/96764/bitnami-gitlab-8.5. ...

  5. 谷歌上不去,长期的解决方案。在稳定高速Google和Gmail

    对稳定Google神器 国内Google很不稳定,缓慢并经常上不去,由"我想去Google",安全和稳定的使用Google.Gmail.Google+所以通常需要特殊的手段岗位胜任 ...

  6. Windows 2008 R2安装.NET Framework 4提示灾难性故障解决方法

    原因:WINDOWS 2008的安全设置方案取消了C盘根目录的Users权限,只给administrator和system权限,结果在打补丁时就无法更新(安装.net4需要安装windows6.1-K ...

  7. Ext,保存输入记录,并会提示输入

    Ext的ComboBox组件使用非常多,通过配置输入框可以被允许成为一个.并可以存储输入记录,记录提示的基础,然后进行再次进入,以提高的用户体验输入操作. 代码非常easy,基本操作,如以下: // ...

  8. Integer比较

    /** * @time 2014-06-25 * @author Cao HaiCheng * */ public class demo { public static void main(Strin ...

  9. codeigniter 该脚本在运行300s超时退

    直接看代码, file:system/core/CodeIgniter.php /* 102  * -------------------------------------------------- ...

  10. ERROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;10.16.115.101&#39; (111)

    ubuntu安装之后mysql,使用apt-get安装命令,默认为同意只本地访问 root@idata1:~/software# mysql -uroot -p123456 -h10.16.115.1 ...