深入理解javaScript的深复制和浅复制
javascript有五种基本数据类型(也就是简单数据类型),它们分别是:Undefined,Null,Boolean,Number和String。还含有一种复杂数据类型,就是对象
注意Undefined和Null的区别,Undefined类型只有一个值,就是undefined,Null类型也只有一个值,也就是null
Undefined其实就是已声明未赋值的变量输出的结果
null其实就是一个不存在的对象的结果
var c;
console.log(c)//undefined
console.log(document.getElementById('wsscat'))//没有id为wsscat的节点,输出null
简单的数据类型和复杂的数据类型有以下重要的区别
对于简单数据类型
它们值在占据了内存中固定大小的空间,并被保存在栈内存中。当一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本,还有就是不能给基本数据类型的值添加属性
var a = 1;
var b = a;
a.attr = 'wsscat';
console.log(a.attr)//undefined
上面代码中a就是简单数据类型(Number),b就是a的副本,它们两者都占有不同位置但相等的内存空间
对于复杂的数据类型
复杂的数据类型即引用类型,它的值是对象,保存在堆内存中,包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象。
var obj = {
name:'wsscat',
age:0
}
var obj2 = obj;
obj2['c'] = 5;
console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
console.log(obj2);////Object {name: "wsscat", age: 0, c: 5}

我们可以看到obj赋值给obj2后,当我们更改其中一个对象的属性值,两个对象都发生了改变,究其原因局势因为obj和obj2这两个变量都指向同一个指针,赋值只是复制了指针,所以当我们改变其中一个的值就会影响另外一个变量的值
浅拷贝
其实这段代码就是浅拷贝,有时候我们只是想备份数组,但是只是简单让它赋给一个变量,改变其中一个,另外一个就紧跟着改变,但很多时候这不是我们想要的
var obj = {
name:'wsscat',
age:0
}
var obj2 = obj;
obj2['c'] = 5;
console.log(obj);//Object {name: "wsscat", age: 0, c: 5}
console.log(obj2);////Object {name: "wsscat", age: 0, c: 5}
深拷贝
数组
对于数组我们可以使用slice()和concat()方法来解决上面的问题
slice
var arr = ['wsscat', 'autumns', 'winds'];
var arrCopy = arr.slice(0);
arrCopy[0] = 'tacssw'
console.log(arr)//['wsscat', 'autumns', 'winds']
console.log(arrCopy)//['tacssw', 'autumns', 'winds']
concat
var arr = ['wsscat', 'autumns', 'winds'];
var arrCopy = arr.concat();
arrCopy[0] = 'tacssw'
console.log(arr)//['wsscat', 'autumns', 'winds']
console.log(arrCopy)//['tacssw', 'autumns', 'winds']
对象
对象我们可以定义一个新的对象并遍历新的属性上去实现深拷贝
var obj = {
name:'wsscat',
age:0
}
var obj2 = new Object();
obj2.name = obj.name;
obj2.age = obj.age
obj.name = 'autumns';
console.log(obj);//Object {name: "autumns", age: 0}
console.log(obj2);//Object {name: "wsscat", age: 0}
当然我们可以封装好一个方法来处理对象的深拷贝,代码如下
var obj = {
name: 'wsscat',
age: 0
}
var deepCopy = function(source) {
var result = {};
for(var key in source) {
if(typeof source[key] === 'object') {
result[key] = deepCopy(source[key])
} else {
result[key] = source[key]
}
}
return result;
}
var obj3 = deepCopy(obj)
obj.name = 'autumns';
console.log(obj);//Object {name: "autumns", age: 0}
在javascript中函数也是一种数据,能够像操作一个对象对它进行操作。并且javascript不进行数据类型检查,数组可以存放任何东西,在下面代码中我们不但在数组中存放了函数,并且也可以在存放一个执行函数的返回值,所以数组前两个数据存放都是函数执行返回值
var funcA = function() {
console.log("funcA");
return "hello funA";
}
var funcB = function() {
console.log("funcB");
return "hello funB";
}
var funcC = function() {
console.log("funcC");
return "hello funC";
}
var arr = [funcA(), funcB(), funcC];
console.log(arr);
arr[2]();
.png)
深入理解javaScript的深复制和浅复制的更多相关文章
- js中的深复制与浅复制
前言 所谓深复制与浅复制(深拷贝与浅拷贝),乍一听感觉听高大上,像是一个非常难理解的概念,其实我们平常项目开发都是在用的,只是你可能不知道该怎么叫它的名字而已,就像你听熟了一首歌,就是不知道这首歌叫什 ...
- iOS 集合的深复制与浅复制
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...
- 实现 $.extend 的深复制和浅复制
$.extend 是jquery常用的一个方法,该方法通过传第一个布尔型参数可以指定为深复制还是浅复制,如何使用不在本文讨论. 先来理解下什么是深复制: var ob1 = {'name' : 'Ja ...
- 深复制与浅复制&&strong,copy修饰符总结
又是一个老生常谈的话题,可是貌似这个问题,好多ios开发工程师并不能理解透彻,所以简单记录分析一下深复制与浅复制的原理以及strong,copy修饰符的原理和使用. 一.深复制与浅复制 ...
- javascript 数组和对象的浅复制和深度复制 assign/slice/concat/JSON.parse(JSON.stringify())
javascript 数组和对象的浅度复制和深度复制在平常我们用 ‘=’来用一个变量引用一个数组或对象,这里是‘引用’而不是复制下面我们看一个例子引用和复制是什么概念 var arr=[1,2,3,' ...
- js的深复制与浅复制
什么是深复制和浅复制? 深复制和浅复制的概念只存在于对象array和数组obj上. 浅复制是:模糊复制,就是不管对方是字符串类型还是引用类型都通通复制过来.结果两个变量的内容会同时变化. 深复制是:有 ...
- .Net深复制、浅复制
在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...
- C++学习基础七——深复制与浅复制
一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量, 当深 ...
- php对象当参数传递 && php深复制和浅复制
把对象当参数传递给方法,在方法里改过对象后,影响到外面的对象 因为对象是引用传递过去的 class Book { public $name; public function __construct( ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
随机推荐
- 2016年最全面的VR资源盘点,不只有VR视频播放器还有具体到步骤的VR资源
2016年过去了,有多少人开始使用VR来观看我们喜欢的视频资源呢?比传统视频更高的沉浸感,甚至在VR眼镜的视角中,自己仿佛化生成视频中的主角一般.然而,这种体验只有VR眼镜还是不行的,还需要有一个VR ...
- iOS 生产证书 分类: ios相关 app相关 2015-05-22 14:49 175人阅读 评论(0) 收藏
首先登陆https://developer.apple.com(99美元账号) 选择iOS Developer program 板块下的 Certificates,Identifiers & ...
- mybatis--常见的错误
1.没有在configuration.xml配置对应的sql配置文件 错误: Error updating database. Cause: java.lang.IllegalArgumentExce ...
- [转] 如何让CloudStack使用KVM创建Windows实例成功识别并挂载数据盘
在使用kvm给windows虚拟机动态挂载virtio类型的硬盘时候遇到问题,通过下面的文章知道需要安装virtio驱动,从而解决问题使挂在正常,在此处mark一下 问题产生背景: 使用CloudSt ...
- 更改Windows Live Writer默认日志与草稿保存路径
目的:把保存Windows Live Writer的日志与草稿文件夹My Weblog Posts移动到E:\Blog\路径下 用mklink命令,创建E:\Blog\路径下的My Weblog Po ...
- Yii实现Password Repeat Validate Rule
在使用Yii时遇到这样的需求:在一个注册的页面输入两次密码,并验证两次输入是否一致.可是password的repeat的字段在数据库 并不存在.问题来了,如何创建一个password_repeat的属 ...
- Lamp环境下设置绑定apache域名
先进入apache配置目录 [root@iZ233vkrtsiZ local]# cd /usr/local/apache/conf/vhost 然后找到自己网站的配置.以本站为例 [root@iZ2 ...
- Angular - - form.FormController、ngModel.NgModelController
form.FormController FormController跟踪所有他所控制的和嵌套表单以及他们的状态,就像有效/无效或者脏值/原始. 每个表单指令创建一个FormController实例. ...
- AnsiIO
1.文件数据内容,元数据内容 i节点ls -l err.txt-rw-rw-r-- 1 csgec csgec 50 Jun 23 11:19 err.txt-:普通文件(文件类型)rw-:属主用户拥 ...
- NodeMCU之旅(二):断线自动重连,闪烁连接状态
事件监听器 NodeMCU采用了事件响应的方式.也就是说,只需为事件设置一个回调函数,当事件发生时,回调函数就会被调用. 注册事件监听器 wif.sta.eventMonReg() 开始监听 wifi ...