文档章节

js 多层深拷贝

appleZ
 appleZ
发布于 2015/04/08 15:23
字数 418
阅读 25
收藏 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
博文 38
码字总数 9774
作品 0
深圳
私信 提问
深入JavaScript基础之深浅拷贝

最近在学到JavaScript对象的深拷贝和浅拷贝做了一些比较,将实际开发的点和基础点做了些小结,话不多说,开始进入主题吧。 基础认识---基本类型 基础认识---引用类型 浅拷贝的实现-对象&&数组...

楚梦浮生
07/30
0
0
关于JSON.parse(JSON.stringify(obj))实现深拷贝应该注意的坑

我们一般用来深拷贝,其过程说白了 就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象;序列化的作用是存储(对象本身存储的只是一个地址映射,...

该帐号已被查封
08/14
0
0
WEB前端学习JavaScript知识点:说清楚深拷贝和浅拷贝的区别

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

web前端小辰
05/28
0
0
一个后端眼中的jQuery的extend方法

概述 我看的是3.1.0版本的,先上一段代码吧,不要版本都不一样那就尴尬了,这段代码看着没有多少,但我相信这基本上是这个世界上执行的最多的代码了,再不济也是一个之一。 直接看代码有一点...

trayvon
2017/10/20
0
0
javascript集锦(一)

javascript集锦(一): javascript作用域: function myFun(){test = 123;}myFun(); //执行myFun后, test在myFun中没有声明var, 被视作全局变量alert(test); //123 javascript闭包:闭包可以记...

ihaolin
2014/03/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

控制台打印图片

function dev(){ if (window.console){ console.log("%c\n ", "font-size:100px;background:url('http://gmcyzs.com/resources/images/logo.png') no-repeat"); console.log('%c 深务平台,\......

羊皮卷
16分钟前
0
0
MyBaties的二级缓存

二级缓存介绍 在上文中提到的一级缓存中,其最大的共享范围就是一个SqlSession内部,那么如何让多个SqlSession之间也可以共享缓存呢,答案是二级缓存。 当开启二级缓存后,会使用CachingExec...

嘴角轻扬30
17分钟前
2
0
10.新增博客功能-结束语---《Beetl视频课程》

本期视频实现发布新博客功能 一起学beetl目录:https://my.oschina.net/u/1590490?tab=newest&catalogId=6214598 作者:GK 教程进入了尾声,该讲的知识点基本讲到了,本节课不会讲新的知识点。...

Gavin-King
22分钟前
3
0
SpringBoot项目热部署

IntelliJ IDEA开发工具 1.需要在pom.xml文件中加入以下依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> ......

llsydn
23分钟前
2
0
JVM问题排查也不是很难--工具使用

目录 概述 环境准备 工具介绍 远程连接方式 开启JMX 工具远程连接 参考文献 概述 线上环境中,程序越来越慢,一头雾水?遇到程序经常宕机,但找不到原因?排查问题却经常记不住命令? 那是没找到好...

java_龙
27分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部