JavaScript 中的对象深度复制(Object Deep Clone)
JavaScript中并没有直接提供对象复制(Object Clone)的方法。
JavaScript中的赋值,其实并不是复制对象,而是类似`c/c++`中的引用(或指针),因此下面的代码中改变对象b中的元素的时候,也就改变了对象a中的元素。
a = {k1:1, k2:2, k3:3};
b = a;
b.k2 = 4;
如果只想改变b而保持a不变,就需要对对象a进行复制。
用jQuery进行对象复制
在可以使用jQuery的情况下,jQuery自带的extend
方法可以用来实现对象的复制。
a = {k1:1, k2:2, k3:3};
b = {};
$.extend(b,a);
自定义clone()方法来实现对象复制
1.下面的方法,是给Object的原型(prototype)添加深度复制方法(deep clone)。
Object.prototype.clone = function() {
// Handle null or undefined or function
if (null == this || "object" != typeof this)
return this;
// Handle the 3 simple types, Number and String and Boolean
if(this instanceof Number || this instanceof String || this instanceof Boolean)
return this.valueOf();
// Handle Date
if (this instanceof Date) {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
// Handle Array or Object
if (this instanceof Object || this instanceof Array) {
var copy = (this instanceof Array)?[]:{};
for (var attr in this) {
if (this.hasOwnProperty(attr))
copy[attr] = this[attr]?this[attr].clone():this[attr];
}
return copy;
}
throw new Error("Unable to clone obj! Its type isn't supported.");
}
所有对象可以直接使用`.clone()`
var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null}]];
var b=a.clone();
2.使用额外的工具函数实现,适用于大部分对象的深度复制(Deep Clone)。
function clone(obj) {
// Handle the 3 simple types, and null or undefined or function
if (null == obj || "object" != typeof obj) return obj; // Handle Date
if (obj instanceof Date) {
var copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
// Handle Array or Object
if (obj instanceof Array | obj instanceof Object) {
var copy = (obj instanceof Array)?[]:{};
for (var attr in obj) {
if (obj.hasOwnProperty(attr))
copy[attr] = clone(obj[attr]);
}
return copy;
}
throw new Error("Unable to clone obj! Its type isn't supported.");
}
用法类似:
var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null}]];
var b=clone(a);
测试
用上面两种方法都可以得到同样的结果。
至于用哪个怎么用,取决于你的喜好/习惯了 :) 就本人来说,我更倾向于使用原型的方法啦,方便嘛,啊哈哈哈~
你想测试结果的话,直接复制代码运行:
var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,undefined,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null,"f":function(){return 2;}}],function(){}];
console.log("a=",a);
console.log("b=a.clone();");
b=a.clone();
console.log("JSON.stringify(a)==JSON.stringify(b) = ",JSON.stringify(a)==JSON.stringify(b));
console.log("JSON.stringify(a)===JSON.stringify(b) = ",JSON.stringify(a)===JSON.stringify(b));
console.log("JSON.stringify(a) = ",JSON.stringify(a));
console.log("JSON.stringify(b) = ",JSON.stringify(b));
console.log("a[2]=123,b[2]=55555");
a[2]=123,b[2]=55555;
console.log("a=",a,"\t\t","b=",b); console.log("b=clone(a);");
b=clone(a);
console.log("JSON.stringify(a)==JSON.stringify(b) = ",JSON.stringify(a)==JSON.stringify(b));
console.log("JSON.stringify(a)===JSON.stringify(b) = ",JSON.stringify(a)===JSON.stringify(b));
console.log("JSON.stringify(a) = ",JSON.stringify(a));
console.log("JSON.stringify(b) = ",JSON.stringify(b));
console.log("a[2]=1234,b[2]=33333");
a[2]=1234,b[2]=33333;
console.log("a=",a,"\t\t","b=",b);
可以看到, 输出结果 `a` 和 `b` 是相等的,但是 改变 `a` 的元素的值, 并不会影响到 `b` 的元素。
访问Github,get更多技能:https://github.com/lzpong/H5_JS_Tools。
JavaScript 中的对象深度复制(Object Deep Clone)的更多相关文章
- 深入探讨JavaScript如何实现深度复制(deep clone)
在代码复用模式里面有一种叫做“复制属性模式”(copying properties pattern).谈到代码复用的时候,很有可能想到的是代码的继承性(inheritance),但重要的是要记住其最终 ...
- javascript中的对象拷贝
js中的数据类型 在介绍javascript中的对象的拷贝之前,我先介绍一个基础的东西,javascript中的数据类型. 我们做前端的应该都知到在es6 之前,javascript中的数据类型Boo ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
- Javascript 中判断对象为空
发现了一个巧妙的实现: 需要检查一个对象(Object)是否为空,即不包含任何元素.Javascript 中的对象就是一个字典,其中包含了一系列的键值对(Key Value Pair).检查一个对象是 ...
- JavaScript中判断对象类型方法大全1
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
- (转)javascript中的对象查找
本文转自:http://otakustay.com/object-lookup-in-javascript/ ---很棒的一篇文章,作者的其他文章还暂时没读,但相信作者是一个谦虚 谨慎的好工程师 近 ...
- (转)javascript中event对象详解
原文:http://jiajiale.iteye.com/blog/195906 javascript中event对象详解 博客分类: javaScript JavaScriptCS ...
- JavaScript中判断对象类型的种种方法
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
- JavaScript中的对象描述符(属性特性)
我们先创建一个对象: var person = { name: "Nicholas", _job: "Software Engineer", sayName: ...
随机推荐
- Css雪碧图
Css雪碧图: CSS雪碧 即CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,然后利用css的背景定位来显示需要显示的图片部分. 原理 ...
- mybatis-databaseIdProvider多数据库支持
<select id="selectPerson" parameterType="int" parameterMap="deprecated&q ...
- 浏览器http的缓存机制
原文出处-----分享从伯乐在线看到的一篇好文章 http://web.jobbole.com/85509/ 针对浏览器的http缓存的分析也算是老生常谈了,每隔一段时间就会冒出一篇不错的文章,其原 ...
- Junit4X系列--hamcrest的使用
OK,在前面的一系列博客里面,我整理过了Assert类下面常用的断言方法,比如assertEquals等等,但是org.junit.Assert类下还有一个方法也用来断言,而且更加强大.这就是我们这里 ...
- java IO(二):字节流
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- 豹哥嵌入式讲堂:ARM知识概要杂辑(4)- Cortex-M处理器性能指标
1.处理器的性能指标 用于评价CPU的性能指标非常多,不同的性能侧重点下的测试标准可能得出的指标值不同,下面介绍嵌入式行业广泛使用的两个经典的测试标准. 1.1 Dhrystone标准 Dhrysto ...
- java to kotlin (2) - lambda编程
前言 Kotlin Note 是我学习kotlin整理笔记向博客,文章中的例子参考了kotlin in action这本书籍,同时我也极力推荐这本书,拥有Java基础的人可以很快的就使用kotlin来 ...
- ATS 分级缓存
理解缓存分级cache hierarchies 缓存分级是由彼此能够相互通信的各级缓存组成的,ATS支持几种类型的缓存分级.所有的缓存分级都有父子缓存概念. 父缓存位于缓存分级的较高级别,ATS能将请 ...
- C#面向对象方式设置、读取应用配置
关注点: 1.用面向对象方式的方式(get,set)访问和设置配置项 2.“CallerMemberName”在.net 4以下的变通方式 最后一周了,大伙都进入过年模式了.身还在,心已远.最近事情不 ...
- Win7-64位+Oracle11.2g+使用PLSQL_Developer 的解决办法
1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)下载instantclient-basic-win ...