js中的深复制和浅复制
在实际情况中经常会遇到对对象复制的问题。比如在处理项目中的一笔多结构的数据存储或者调用,这个时候你就要对对象(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中的深复制和浅复制的更多相关文章
- js中的深复制与浅复制
前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- Java中的深复制与浅复制
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...
- C#中的深复制与浅复制
C#中分为值类型和引用类型,值类型的变量直接包含其数据,而引用类型的变量则存储对象的引用. 对于值类型,每个变量都有自己的数据副本,对一个变量的操作不可能影响到另一个变量.如 class Progra ...
- Java中的clone()----深复制,浅复制
这篇文章主要介绍了Java中对象的深复制(深克隆)和浅复制(浅克隆) ,需要的朋友可以参考下 1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他 ...
- js的深复制与浅复制
什么是深复制和浅复制? 深复制和浅复制的概念只存在于对象array和数组obj上. 浅复制是:模糊复制,就是不管对方是字符串类型还是引用类型都通通复制过来.结果两个变量的内容会同时变化. 深复制是:有 ...
- .Net深复制、浅复制
在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...
- C++学习基础七——深复制与浅复制
一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...
- iOS 集合的深复制与浅复制
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...
随机推荐
- js分秒必争
将函数和对象合写在一起时,函数就变成了“方法”(method): //当函数赋值给对象的属性,我们称之为 //方法.所有的JavaScript的对象都含有方法 var a=[]; //创 ...
- Python 第一个Python项目Hello,Python 学习之路(二)
print("Hello,Python")
- python logging模块可能会令人困惑的地方
python logging模块主要是python提供的通用日志系统,使用的方法其实挺简单的,这块就不多介绍.下面主要会讲到在使用python logging模块的时候,涉及到多个python文件的调 ...
- SQL Server2005索引碎片分析和解决方法
SQL Server2005索引碎片分析和解决方法 本文作者(郑贤娴),请您在阅读本文时尊重作者版权. 摘要: SQL Server,为了反应数据的更新,需要维护表上的索引,因而这些索引会形成碎片.根 ...
- php的cookie和session相同主域名共享
如何使用chrome查看cookie和session详见另一篇文章,点这里 首先说cookie, $cookieDomain = '.elf.com'; setcookie('elf', 'im el ...
- JavaScript拼接字符串传递多个参数
var ftOpreat = function (value,rows){ var v = rows.Version; var preview = "<a href=\"#\ ...
- css3中的颜色
1颜色.color:rgba(R,G,B,A) R,G,B是分别代笔红,绿,蓝值是在0到255之间的数也可以是0.0% - 100.0%,A代表的是透明度0到1之间. 2.渐变.background- ...
- hdoj 1002 A+B(2)
Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...
- ORA-12543: TNS:destination host unreachable
在连接Oracle数据库时,如果使用Tnsnames.ora中配置的数据源名称有时会报 ORA-12543: TNS:destination host unreachable 异常,比如:在Tnsna ...
- Linux 如何安装memcache?
原有memcache所在机器损坏,需要在新的Linux机器上安装memcache,具体步骤如下: 1.使用Linux机器的root权限登陆 2.安装libevent 下载地址:http://libev ...