JavaScript对象之深度克隆
也不知道从什么时候开始,前端圈冒出了个新词:对象深度克隆。看起来好像很高大上的样子,实际上并不新鲜,在我们的实际项目开发中,你可能早已用到,只不过由于汉字的博大精深,有些原本很简单的事物被一些看似专业的词汇稍加修饰,就变得神秘起来了。
首先为什么要将一个对象进行深克隆?请允许我进行一个猜测:你有时一定会认为js的内置对象document太长,那么你可能会这样做:
var d = document;
d.by = function(id){
return d.getElementById(id);
};
d.by('id').innerHTML = 'hello sentsin';
上述代码对document.getElementById进行了简化,同时在原document对象中也增加了一个by的成员方法,你可以通过document.hasOwnProperty('by')返回的状态值来验证你的判断。再看下面一个例子。
var person = {name: '贤心', profession: '前端开发', place: '杭州'};
var newPerson = person;
newPerson.age = '24';
console.log(person);
//结果:{name: '贤心', profession: '前端开发', place: '杭州', age: 24}
由此可见,将一个对象通过简单的传递给一个新的变量时,仅仅只是给该对象增添了一个别名。这意味着,通过对该别名的操作,原有对象键值会发生改变。但问题在于,有时我们希望newPerson完全独立于person,彼此之间不存在同步关系,那么就需要生成一个副本,请看例子:
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};
//测试
var obj = {a: 0, b: 1, c: 2};
var arr = [0, 1, 2];
//执行深度克隆
var newobj = cloneObj(obj);
var newarr = cloneObj(arr);
//对克隆后的新对象进行成员删除
delete newobj.a;
newarr.splice(0,1);
console.log(obj, arr, newobj, newarr);
//结果: {a: 0, b: 1, c: 2}, [0, 1, 2], {b: 1, c: 2}, [1, 2];
这便是所谓的对象克隆。不过有几处需要解释一下。代码中的JSON对象及其成员方法stringify和parse属于ECMAScript5规范,它们分别负责将一个对象(包括数组对象)转换成字符串,和还原,从而实现对象的深拷贝。那么对于低级浏览器(如IE),拷贝数组的话,可以用newobj.concat(obj),而普通对象,就索性枚举赋值好了。
JavaScript对象之深度克隆的更多相关文章
- javascript对象的深度克隆
在做项目的时候需要向对象里面添加新属性,又不想修改原对象.于是就写: var newObj = oldObj,但是新对象属性改变后就对象也会跟着改变,这是因为无论是新对象还是旧对象,指向的内存地址都是 ...
- javascript中对象的深度克隆
记录一个常见的面试题,javascript中对象的深度克隆,转载自:http://www.2cto.com/kf/201409/332955.html 今天就聊一下一个常见的笔试.面试题,js中对象的 ...
- JavaScript实现对象的深度克隆及typeof和instanceof【简洁】【分享】
JavaScript实现对象的深度克隆 代码实现如下: <!DOCTYPE html> <html lang="en"> <head> < ...
- js对象的深度克隆
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- MyDAL - 引用类型对象 .DeepClone() 深度克隆[深度复制] 工具 使用
索引: 目录索引 一.API 列表 .DeepClone() 用于 Model / Entity / ... ... 等引用类型对象的深度克隆 特性说明 1.不需要对对象做任何特殊处理,直接 .Dee ...
- JAVA对象的深度克隆
有时候,我们需要把对象A的所有值复制给对象B(B = A),但是这样用等号给赋值你会发现,当B中的某个对象值改变时,同时也会修改到A中相应对象的值! 也许你会说,用clone()不就行了?!你的想法只 ...
- 【JavaScript代码实现三】JS对象的深度克隆
function clone(Obj) { var buf; if (Obj instanceof Array) { buf = []; // 创建一个空的数组 var i = Obj.length; ...
- JavaScript的深度克隆
1.JavaScript的五种基本数据类型: Number.String.Boolean.null.undefined. 2.typeof返回的六种数据类型: Number.String.Boolea ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
随机推荐
- 20145215《网络对抗》Exp9 Web安全基础实践
20145215<网络对抗>Exp9 Web安全基础实践 基础问题回答 SQL注入攻击原理,如何防御? SQL注入攻击就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符 ...
- mac 上sublime3安装编码插件
我们常常会遇到这样的问题:我们使用 mac 的时候,从 windows 上接受过来的文档通过 sublime3打开之后就是乱码,这个时候需要安装相对应的编码插件才能正常查看. 1. 打开 sublim ...
- 转:scrollWidth,clientWidth,offsetWidth的区别
scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大. clientWidth:对象内容的可视区的宽度,不包滚动条等边线,会随对象显示大小的变化而改变. off ...
- shell脚本递归压缩实践
#!/bin/bash Src_Path=/data/www/logs Dst_Path=/data/www/logs_bak for rfile in `find $Src_Path/ -depth ...
- 让div固定在顶部不随滚动条滚动【转】
让div固定在顶部不随滚动条滚动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...
- Redis和Memcached对比【转】
Redis和Memcached对比 这两年 Redis火得可以,Redis也常常被当作 Memcached的挑战者被提到桌面上来.关于Redis与Memcached的比较更是比比皆是.然而,Redis ...
- .Net进阶系列(14)-异步多线程(async和await)(被替换)
1. 方法名前只有async,但是方法中Task实例前没有await关键字,该方法和普通方法没有什么区别,但是会报一个警告. #region 情况一 /// <summary> /// ...
- vue项目首次加载过慢
vue项目优化 浅谈 Vue 项目优化 关于vue在app首次加载缓慢的解决办法 nginx开启缓存 在http部分加入 #要想开启nginx的缓存功能,需要添加此处的两行内容! #设置Web缓存区名 ...
- linux 命令收集 阿里云nginx升级等 查看磁盘空间 版本等
—————————————————— 查磁盘 df -h此命令直观的呈现出磁盘大小有多少Gdf -hl文件系统 容量 已用 可用 已用% 挂载点/dev/hdb2 75G 75G 0 100% /就是 ...
- VS新建项目工具箱图标丢失问题
(1)在电脑里搜索*.tbd文件(2)建一个项目,把需要的工具箱图标加载上,退出 VS. (3)复制一份toolbox.tbd,重命名为toolbox_reset.tbd 然后以后新建项目就可以了.这 ...