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打开新窗口同时关闭旧窗口
Jan 16 Javascript
简短几句jquery代码的实现一个图片向上滚动切换
Sep 02 Javascript
jquery实现点击弹出层效果的简单实例
Mar 03 Javascript
Javascript快速排序算法详解
Dec 03 Javascript
js实现无缝滚动特效
Dec 20 Javascript
Bootstrap table分页问题汇总
May 30 Javascript
JavaScript简单验证表单空值及邮箱格式的方法
Jan 20 Javascript
jQuery使用zTree插件实现可拖拽的树示例
Sep 23 jQuery
原生JS与jQuery编写简单选项卡
Oct 30 jQuery
layui中select,radio设置不生效的解决方法
Sep 05 Javascript
简单实现节流函数和防抖函数过程解析
Oct 08 Javascript
Vuex modules模式下mapState/mapMutations的操作实例
Oct 17 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也可以?成Shell Script
2006/10/09 PHP
PHP 类型转换函数intval
2009/06/20 PHP
PHP中的事务使用实例
2015/05/26 PHP
手把手编写PHP框架 深入了解MVC运行流程
2016/09/19 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
13个绚丽的Jquery 界面设计网站推荐
2010/09/28 Javascript
jQuery LigerUI 使用教程表格篇(1)
2012/01/18 Javascript
jquery 追加tr和删除tr示例代码
2013/09/12 Javascript
JQuery 使用attr方法实现下拉列表选中
2014/10/13 Javascript
javascript删除数组重复元素的方法汇总
2015/06/24 Javascript
JavaScript的MVVM库Vue.js入门学习笔记
2016/05/03 Javascript
JS获取一个未知DIV高度的方法
2016/08/09 Javascript
js正则表达式注册页面表单验证
2016/10/11 Javascript
如何将 jQuery 从你的 Bootstrap 项目中移除(取而代之使用Vue.js)
2017/07/17 jQuery
js处理包含中文的字符串实例
2017/10/11 Javascript
JQuery Ajax动态加载Table数据的实例讲解
2018/08/09 jQuery
原生js实现trigger方法示例代码
2019/05/22 Javascript
python代码制作configure文件示例
2014/07/28 Python
python中self原理实例分析
2015/04/30 Python
windows下ipython的安装与使用详解
2016/10/20 Python
基于Python代码编辑器的选用(详解)
2017/09/13 Python
python dict 相同key 合并value的实例
2019/01/21 Python
django rest framework 过滤时间操作
2020/07/12 Python
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
Swanson中国官网:美国斯旺森健康产品公司
2021/03/01 全球购物
法学研究生自我鉴定范文
2013/12/04 职场文书
九年级家长会邀请函
2014/01/15 职场文书
2014年清明节寄语
2014/04/03 职场文书
学习方法演讲稿
2014/05/10 职场文书
信用卡结清证明怎么写
2014/09/13 职场文书
单位一把手群众路线四风问题整改措施
2014/09/25 职场文书
2014年司法局工作总结
2014/12/11 职场文书
实习介绍信模板
2015/01/30 职场文书
java调用Restful接口的三种方法
2021/08/23 Java/Android
详细聊聊MySQL中慢SQL优化的方向
2021/08/30 MySQL
java协程框架quasar和kotlin中的协程对比分析
2022/02/24 Java/Android