文档章节

js 多层深拷贝

appleZ
 appleZ
发布于 2015/04/08 15:23
字数 418
阅读 24
收藏 0
点赞 0
评论 0

背景(数组为例):

js数组复制最有效的方法是直接使用slice和concat方法

var testA = [1, 3, 5];
var copya = [].slice.call(testA);
console.log(testA[0]);//1 
copya[0] = 2;
console.log(testA[0]);//1 

var testAA = [[1]];
var copyaa = [].slice.call(testAA);
console.log(testAA[0][0]);//1
copyaa[0][0] = 2;
console.log(testAA[0][0]);//2 问题出现

原因分析:只复制了一维,内部仍是引用;

解决:

先写个curry化 用来判断类型 seajs中也是这种 简单方便 后面会用到

var toString = Object.prototype.toString;
var isType = function(type){ //curry化
	return function(obj){
		return toString.call(obj) == "[object " + type + "]";//例如 "[object Array]"
	}
}
var isArray = isType("Array");
var isObject = isType("Object");

定义几个变量用来测试

var testOA = {a:[1]};
var testAO = [{a:1}];
var testOO = {a:{b:1}};
var testAA = [[1]];

先做下Object的处理:

function copyO(obj){//剥离Object
	var ret = {}
	if(isObject(obj)){ 
		for(var key in obj){
			if(obj.hasOwnProperty(key)){
				var child = obj[key];
				ret[key] = child
				if(isObject(child)){
					ret[key] = arguments.callee(child);
				}
			}
		}
	}else{
		ret = obj;
	}
	return ret;
}

测试结果:

var copyoo = copyO(testOO);
copyoo.a.b = 2;
copyoo.log(testOO.a.b);//1
copyoo.a = null;
console.log(testOO.a);//Object {b: 1}

再做数组的处理:

function copyA(obj){
	var ret = {};
	if(isArray(obj)){
		ret = [].slice.call(obj);
		for(var i = 0; i < ret.length; i++){
			ret[i] = arguments.callee(ret[i]);
		}
	}else{
		ret = obj;
	}
	return ret;
}

测试结果:

var copya = copyA(testAA);
copya[0][0] = 2;
console.log(testAA[0][0]);//1
copya[0].length = 0;//
console.log(testAA[0]);//[1]

合并:

function deepCopy(obj){
	var ret = {};
	if(isArray(obj)){
		ret = [].slice.call(obj);
		for(var i = 0; i < ret.length; i++){
			ret[i] = arguments.callee(ret[i]);
		}
	}else if(isObject(obj)){
		for(var key in obj){
			if(obj.hasOwnProperty(key)){
				var child = obj[key];
				ret[key] = arguments.callee(child);
			}
		}
	}else{
		ret = obj;
	}
	return ret;
}

测试结果:

var copyoa = deepCopy(testOA);
copyoa["a"][0] = 2;
console.log(testOA["a"][0]);//1 
copyoa["a"] = null;//
console.log(testOA["a"]);//[1]

var copyao = deepCopy(testAO);
copyao[0]["a"] = 2;
console.log(testAO[0]["a"]);//1
copyao[0].length = 0;//
console.log(testAO[0]);//Object {a: 1}

可以继续合并写法,这里不做了。。

© 著作权归作者所有

共有 人打赏支持
appleZ
粉丝 1
博文 25
码字总数 9774
作品 0
深圳
WEB前端学习JavaScript知识点:说清楚深拷贝和浅拷贝的区别

Web前端开发工程师是一个很新的职业,是从事Web前端开发工作的工程师。主要进行网站开发,优化,完善的工作。网页制作是Web 1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行...

web前端小辰 ⋅ 05/28 ⋅ 0

第一章--JavaScript简介

1. JavaScript的构成 1.1. ECMAScript ECMAScript规定了核心语言的组成部分分别为:语法、类型、语句、关键字、保留字、操作符、对象。 宿主环境:Web浏览器、Node、Adobe Flash。 1.2. DOM...

lovewt ⋅ 06/05 ⋅ 0

从JS对象开始,谈一谈“不可变数据”和函数式编程

文章转载自:https://segmentfault.com/a/1190000008780076 作为前端开发者,你会感受到JS中对象(Object)这个概念的强大。我们说“JS中一切皆对象”。最核心的特性,例如从String,到数组,再...

朱先忠老师 ⋅ 05/20 ⋅ 0

JavaScript函数式编程之副作用

更多相关内容见博客 github.com/zhuanyongxi… 概念: 副作用是在计算结果的过程中,系统状态的一种变化,或者与外部世界进行的可观察的交互。 上文中的纯函数的概念很严格,这个副作用的概念...

砖用冰西瓜 ⋅ 06/14 ⋅ 0

低门槛彻底理解JavaScript中的深拷贝和浅拷贝

在说深拷贝与浅拷贝前,我们先看两个简单的案例: 按照常规思维,应该和一样,不会因为另外一个值的改变而改变,而这里的 却随着的改变而改变了。同样是变量,为什么表现不一样呢?这就要引入...

lunaqi ⋅ 05/11 ⋅ 0

js基本数据类型不妨回头再看看

JS的基本数据类型有哪些呢? js基本数据类型: es5中的基本数据类型有:Undefined、Null、Boolean、Number、String、Object。 es6中新加一个数据类型 symbol 检测当前变量的数据类型方法 ty...

不空大的Timo ⋅ 05/26 ⋅ 0

JS中的深拷贝与浅拷贝了解一下

在使用Vue做项目的时候,通常会有许多组件间传递对象的情况。如果只是简单的赋值的话(浅拷贝),是很危险的,因为你不知道什么情况下这个值就被修改了,还一脸蒙蔽,所以我们需要进行深拷贝...

tinaawang ⋅ 05/28 ⋅ 0

Javascript对象的深浅拷贝

开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。 其实都是copy。 深拷贝(递归复制,复制所有层级,独立副本,一个完全和原来对象属性无关的副本) 返回对象:一个。 传入对...

趁你还年轻233 ⋅ 04/11 ⋅ 0

由js数组类型判断触发的浪漫思绪

一、前言 众所周知,js是门“动态”、“弱类型”编程语言,这意味着在js中可以很任性的定义变量,任性的同时也意味着需常在开发中对变量做类型判断,曾几何时,对数组变量的类型的判断是件很...

hanmin ⋅ 06/08 ⋅ 0

Java使用POM一JAR包的形式管理JavaScript文件-WebJars

说明:原来JS框架还可以使用POM进行管理的。WebJars是一个很神奇的东西,可以让大家以JAR包的形式来使用前端的各种框架、组件。 什么是WebJars 什么是WebJars?WebJars是将客户端(浏览器)资...

easonjim ⋅ 01/18 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 36分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 38分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 49分钟前 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 51分钟前 ⋅ 0

我的第一篇个人博客

虽然这是个技术博客,但是,我总是想写一些自己的东西,所有就大胆的在这里写下了第一篇非技术博客。技术博客也很久没有更新,个人原因。 以后自己打算在这里写一些非技术博客,可能个人观点...

Mrs_CoCo ⋅ 52分钟前 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 52分钟前 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 56分钟前 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 今天 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部