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 相关文章推荐
小议Javascript中的this指针
Mar 18 Javascript
php中给js数组赋值方法
Mar 10 Javascript
JS限制文本框只能输入数字和字母方法
Feb 28 Javascript
javascript HTML5 Canvas实现圆盘抽奖功能
Apr 11 Javascript
响应式表格之固定表头的简单实现
Aug 26 Javascript
bootstrap datetimepicker2.3.11时间插件使用
Nov 19 Javascript
js实现类bootstrap模态框动画
Feb 07 Javascript
vuex提交state&&实时监听state数据的改变方法
Sep 16 Javascript
使用JS判断页面是首次被加载还是刷新
May 26 Javascript
微信小程序嵌入腾讯视频源过程详解
Aug 08 Javascript
Vue实现兄弟组件间的联动效果
Jan 21 Javascript
vue实现日历表格(element-ui)
Sep 24 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
第二节 对象模型 [2]
2006/10/09 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
thinkphp框架page类与bootstrap分页(美化)
2017/06/25 PHP
[原创]PHP global全局变量经典应用与注意事项分析【附$GLOBALS用法对比】
2019/07/12 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
Auntion-TableSort国人写的一个javascript表格排序的东西
2007/11/12 Javascript
jQuery EasyUI API 中文文档 - Tabs标签页/选项卡
2011/10/01 Javascript
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
UpdatePanel和Jquery冲突的解决方法
2013/04/01 Javascript
Jquery+CSS3实现一款简洁大气带滑动效果的弹出层
2013/05/15 Javascript
轮播的简单实现方法
2016/07/28 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
原生JS实现垂直手风琴效果
2017/02/19 Javascript
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
详解Vue2 添加对scss的支持
2019/01/02 Javascript
Nodejs核心模块之net和http的使用详解
2019/04/02 NodeJs
Django中使用locals()函数的技巧
2015/07/16 Python
详解Django+Uwsgi+Nginx的生产环境部署
2018/06/25 Python
详解django自定义中间件处理
2018/11/21 Python
python采集微信公众号文章
2018/12/20 Python
快速解决pyqt5窗体关闭后子线程不同时退出的问题
2019/06/19 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
2019/12/20 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
python爬虫泛滥的解决方法详解
2020/11/25 Python
html5 桌面提醒:Notifycations应用介绍
2012/11/27 HTML / CSS
5个你不知道的HTML5的接口介绍
2013/08/07 HTML / CSS
美国宠物用品网站:Value Pet Supplies
2018/03/17 全球购物
linux系统都有哪些运行级别
2016/03/26 面试题
幼儿园保育员辞职信
2014/01/12 职场文书
弘扬职业精神演讲稿
2014/03/20 职场文书
幽默自我介绍演讲稿
2014/08/21 职场文书
党的群众路线教育实践活动个人对照检查剖析材料
2014/09/23 职场文书
2014年德育工作总结
2014/11/20 职场文书
MySQL查看表和清空表的常用命令总结
2021/05/26 MySQL
MySQL8.0的WITH查询详情
2021/08/30 MySQL
Golang 链表的学习和使用
2022/04/19 Golang