在实际情况中经常会遇到对对象复制的问题。比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(json)进行操作,而不同的操作根据不同的需求来定义。其中最常见最普遍的是对对象的复制,重新定义,扩展等。下面我们正对这些问题来进行探讨。要了解对象,我们首先需要了解js的内存分配机制:

var o = {a:1};当我们在给一个变量赋值的时候已经在浏览器中开辟了一块内存出来。这块内存在浏览器中占了一定的空间,这个时候,我们可以称变量 o 为栈,称{a:1}为堆,他们之间的关系可以用下面这个图表示:

我们可以看到,栈上只是存了一个指针,指针就是堆上对象的地址;这个时候我们的程序通过这个指针句柄可以操作堆上的对象;下面我们再声明一个变量b; var b = o;把o复制给b。b通过o获得{a:1}这个对象,但它们并非两个不同的对象,实际上他们的指针都是指向同一个对象。所以当我们通过b重新给{a:1}赋值的时候,我们可以看到o也对应的改变了:

var o = {a:1}, b = o;
b.a = 2;
console.log(o)
//控制台输出提示:Object {a: 2}

  这种简单的对对象赋值引用的方式我们可以称之为浅复制,浅复制故名思义它是对整个对象体复制的,没有开辟新内存,所以就会有牵一发动全身的现象出现。如何避免这样的一种情况呢,我们就必须要考虑对对象进行深度复制了。深度复制是对对象枚举,通过查找最末一层值不为对象的属性,然后将该值赋值给新的对象的同名属性上去,由于字符串或者数字的赋值是开辟新内存的,所以我们可以避免上面的说的改变b而导致o的变化。下面是个简单的例子,说明深度复制的原理:

var o = {a:1};
var b = {};
b.a = o.a;
b.a = 2;
console.log(o)
//Object {a: 1}

  从以上的代码我们可以看到,b的a属性已经不关联o的任何属性了,它开辟了新内存,可以做自己的事情不会影响到a;我们可以写一个简单的函数来对对象进行深度复制:

var deepCopy= function(source) { 

    var result={};

    for (var key in source) {

        result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];

     }
return result;
}

  当然,说到对象不要忘记我们的array,它也是属于对象类型的。但是对于数组我们有更简便的方法可以用

1.slice()

var a = [1];
var b = a.slice(1);

2.concat()

var a = [1];
var b = [].content(a);

3.组合兼容函数,我们直接上zepto的源码:

  function extend(target, source, deep) {
for (key in source)
if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
if (isPlainObject(source[key]) && !isPlainObject(target[key]))
target[key] = {}
if (isArray(source[key]) && !isArray(target[key]))
target[key] = []
extend(target[key], source[key], deep)
}
else if (source[key] !== undefined) target[key] = source[key]
}

  原理和上面写的deepCopy一样,遇到对象就枚举,直到它的值是字符串或者数字,然后给新的对象添加属性并且赋值。

  ps:遗憾的事诺大的underscore.js竟然不支持深度复制,这让我着实头痛。无奈只有选zepto来辅助了。

  

js中的深复制和浅复制的更多相关文章

  1. js中的深复制与浅复制

    前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...

  2. Java中对象的深复制和浅复制详解

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

  3. Java中的深复制与浅复制

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

  4. C#中的深复制与浅复制

    C#中分为值类型和引用类型,值类型的变量直接包含其数据,而引用类型的变量则存储对象的引用. 对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响到另一个变量.如 class Progra ...

  5. Java中的clone()----深复制,浅复制

    这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他 ...

  6. js的深复制与浅复制

    什么是深复制和浅复制? 深复制和浅复制的概念只存在于对象array和数组obj上. 浅复制是:模糊复制,就是不管对方是字符串类型还是引用类型都通通复制过来.结果两个变量的内容会同时变化. 深复制是:有 ...

  7. .Net深复制、浅复制

    在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...

  8. C++学习基础七——深复制与浅复制

    一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...

  9. iOS 集合的深复制与浅复制

    概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...

随机推荐

  1. 设计模式:Context模式

    作者:吴香伟 发表于 2014/09/12 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 Ceph实现中使用了大量派生于Context抽象类的子类,用法简单却很 ...

  2. [Gnu]Centos7 解决 gdb 提示 Missing separate debuginfos

    Centos7 上使用gdb: $ gdb php $ run /home/www/2.php 运行完 run,后面跟着很长的提示: …. Missing separate debuginfos, u ...

  3. cassandra安装

    从官网下载下来的包解压后有100多M,里面包含了已经编译好的全部程序. 按照方法,进入目录后运行 bin/cassandra -f 运行不成功. 然后根据"https://wiki.apac ...

  4. mvc理解篇

    java是面向对象的语言. mvc是一种设计模式,就像论文排版,设置好论文的框架,字体,大小,颜色等,然后把论文内容往里填.mvc的出现让代码的层次更加的清晰,业务通过数据流实现. mvc框架的优点如 ...

  5. EM最大期望化算法

    最大期望算法(Expectation-maximization algorithm,又译期望最大化算法)在统计中被用于寻找,依赖于不可观察的隐性变量的概率模型中,参数的最大似然估计. 在统计计算中,最 ...

  6. C语言打印最长字符串

    编程在一个已知的字符串中找最长单词,假定字符串中只含字母和空格,空格用来分隔不同单词. ]; printf("请输入字符串:"); fgets(p, , stdin); ; ; ; ...

  7. crack.vbs病毒,优盘里所有文件全变成快捷方式

    去了一趟学校打印店,用优盘copy打印了点东西,当时在打印店电脑里打开优盘的时候里面就变成了快捷方式,但没怎么在意.回来之后在自己电脑上居然也这样了.网上一搜是中了crack.vbs病毒了.格式化优盘 ...

  8. 《UML大战需求分析》阅读笔记6

    流程分析三剑客之总结 顺序图,活动图相类似表示活动,状态机图表示状态.分析特点: 顺序图: 强调角色之间的交互,信息明确: 从上到下,从左到右,按时间顺序: 不适合表达复杂特殊情况(循环分支,条件分支 ...

  9. extjs6环境

    安装JDK http://www.oracle.com/technetwork/java/javase/downloads/ 安装到指定路径,例如D:\Java配置环境变量 此电脑—属性—高级系统设置 ...

  10. 一个简单的Windows下的socket程序

    服务器端代码server.cpp: #include <stdio.h> #include <WinSock2.h> #pragma comment(lib,"ws2 ...