文档章节

js 多层深拷贝

appleZ
 appleZ
发布于 2015/04/08 15:23
字数 418
阅读 24
收藏 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

没有更多内容

加载失败,请刷新页面

加载更多

创建第一个react项目

sudo npm i -g create-react-app@1.5.2 create-react-app react-app cd react-apprm -rf package-lock.jsonrm -rf node_modules #主要是为了避免报错npm installnpm start......

lilugirl
今天
1
0
在浏览器中进行深度学习:TensorFlow.js (八)生成对抗网络 (GAN)

Generative Adversarial Network 是深度学习中非常有趣的一种方法。GAN最早源自Ian Goodfellow的这篇论文。LeCun对GAN给出了极高的评价: “There are many interesting recent development...

naughty
今天
0
0
搬瓦工镜像站bwh1.net被DNS污染,国内打不开搬瓦工官网

今天下午(2018年10月17日),继搬瓦工主域名bandwagonhost.com被污染后,这个国内的镜像地址bwh1.net也被墙了。那么目前应该怎么访问搬瓦工官网呢? 消息来源:搬瓦工优惠网->搬瓦工镜像站b...

flyzy2005
今天
3
0
SpringBoot自动配置

本篇介绍下,如何通过springboot的自动配置,将公司项目内的依赖jar,不需要扫描路径,依赖jar的情况下,就能将jar内配置了@configuration注解的类,创建到IOC里面 介绍下开发环境 JDK版本1.8 spr...

贺小五
今天
5
0
命令行新建Maven多项目

参考地址 # DgroupId 可以理解为包名# DartifactId 可以理解为项目名mvn archetype:generate -DgroupId=cn.modfun -DartifactId=scaffold -DarchetypeArtifactId=maven-archetype-quickst......

阿白
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部