文档章节

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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

配置Spring的注解支持

声明:本栏目所使用的素材都是凯哥学堂VIP学员所写,学员有权匿名,对文章有最终解释权;凯哥学堂旨在促进VIP学员互相学习的基础上公开笔记。 配置Spring的注解支持 以上也提到了使用注解来配...

凯哥学堂
41分钟前
0
0
关于Spring Aop存在的一点问题的思考

在本人前面的文章Spring Aop原理之切点表达式解析中讲解了Spring是如何解析切点表达式的,在分析源码的时候,出现了如下将要讲述的问题,我认为是不合理的,后来本人单纯使用aspectj进行试验...

爱宝贝丶
43分钟前
0
0
JavaScript 概述

JavaScript是面向Web的编程语言。绝大多数现代网站都使用了JavaScript,并且所有的现代Web浏览器——基于桌面系统、游戏机、平板电脑和智能手机的浏览器——均包含了JavaScript解释器。这使得...

Mr_ET
今天
0
0
Java Run-Time Data Areas(Java运行时数据区/内存分配)

Java运行时数据区(内存分配) 本文转载官网 更多相关内容可查看官网 中文翻译可参考 2.5. Run-Time Data Areas The Java Virtual Machine defines various run-time data areas that are use...

lichuangnk
今天
0
0
docker learn :services docker-compose.yml

docker-compose.yml定义了服务的运行参数 version: "3" services: web: # replace username/repo:tag with your name and image details image: hub.c.163.com/dog948453219/friendlyhello d......

writeademo
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部