JavaScript对象之深度克隆介绍


Posted in Javascript onDecember 08, 2014

也不知道从什么时候开始,前端圈冒出了个新词:对象深度克隆。看起来好像很高大上的样子,实际上并不新鲜,在我们的实际项目开发中,你可能早已用到,只不过由于汉字的博大精深,有些原本很简单的事物被一些看似专业的词汇稍加修饰,就变得神秘起来了。

首先为什么要将一个对象进行深克隆?请允许我进行一个猜测:你有时一定会认为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 相关文章推荐
通过 Dom 方法提高 innerHTML 性能
Mar 26 Javascript
JQuery AJAX实现目录浏览与编辑的代码
Oct 21 Javascript
jQuery+css实现图片滚动效果(附源码)
Mar 18 Javascript
JS 实现点击a标签的时候让其背景更换
Oct 15 Javascript
js中window.open()的所有参数详细解析
Jan 09 Javascript
Javascript控制div属性动态变化实例分析
Oct 08 Javascript
跟我学习javascript的异步脚本加载
Nov 20 Javascript
酷! 不同风格页面布局幻灯片特效js实现
Feb 19 Javascript
express默认日志组件morgan的方法
Apr 05 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
Oct 24 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
Feb 07 Javascript
vue路由切换时取消之前的所有请求操作
Sep 01 Javascript
SeaJS 与 RequireJS 的差异对比
Dec 08 #Javascript
JavaScript中的ArrayBuffer详细介绍
Dec 08 #Javascript
JS实现仿京东淘宝竖排二级导航
Dec 08 #Javascript
js继承call()和apply()方法总结
Dec 08 #Javascript
ANGULARJS中用NG-BIND指令实现单向绑定的例子
Dec 08 #Javascript
详解Javascript动态操作CSS
Dec 08 #Javascript
jquery.ajax之beforeSend方法使用介绍
Dec 08 #Javascript
You might like
PHP 中的批处理的实现
2007/06/14 PHP
PHP中如何防止外部恶意提交调用ajax接口
2016/04/11 PHP
thinkphp在低版本Nginx 下支持PATHINFO的方法分享
2016/05/27 PHP
PHP中使用mpdf 导出PDF文件的实现方法
2018/10/22 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
PPK 谈 JavaScript 的 this 关键字 [翻译]
2009/09/29 Javascript
JavaScript 组件之旅(三):用 Ant 构建组件
2009/10/28 Javascript
B/S模式项目中常用的javascript汇总
2013/12/17 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
JavaScript将DOM事件处理程序封装为event.js 出现的低级错误问题
2016/08/03 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
2016/09/29 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
Vue三层嵌套路由的示例代码
2018/05/05 Javascript
JS立即执行函数功能与用法分析
2019/01/15 Javascript
JS实现打砖块游戏
2020/02/14 Javascript
NodeJS配置CORS实现过程详解
2020/12/02 NodeJs
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
[36:33]完美世界DOTA2联赛循环赛 Matador vs Forest 第一场 11.06
2020/11/06 DOTA
Python使用chardet判断字符编码
2015/05/09 Python
Windows上配置Emacs来开发Python及用Python扩展Emacs
2015/11/20 Python
对Python协程之异步同步的区别详解
2019/02/19 Python
简单了解python PEP的一些知识
2019/07/13 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
2020/08/07 Python
Laura官网:加拿大女性的顶级时尚目的地
2019/09/20 全球购物
Wallis官网:英国女装零售商
2020/01/21 全球购物
大专毕业自我鉴定
2014/02/04 职场文书
党员干部形式主义个人整改措施
2014/09/17 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
2014年妇委会工作总结
2014/12/10 职场文书
成绩报告单家长评语
2014/12/30 职场文书
作息时间调整通知
2015/04/22 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
创业计划书之闲置物品置换中心
2019/12/25 职场文书
Lakehouse数据湖并发控制陷阱分析
2022/03/31 Oracle
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android