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 相关文章推荐
用正则表达式 动态创建/增加css style script 兼容IE firefox
Mar 10 Javascript
{}与function(){}选用空对象{}来存放keyValue
May 23 Javascript
javascript数组操作(创建、元素删除、数组的拷贝)
Apr 07 Javascript
浅谈JavaScript Array对象
Dec 29 Javascript
jQuery实现页面顶部显示的进度条效果完整实例
Dec 09 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
Mar 19 Javascript
js图片轮播插件的封装
Jul 21 Javascript
Vue核心概念Getter的使用方法
Jan 18 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
Mar 06 Javascript
JavaScript 双向链表操作实例分析【创建、增加、查找、删除等】
Apr 28 Javascript
解决Vue的项目使用Element ui 走马灯无法实现的问题
Aug 03 Javascript
vue 实现图片懒加载功能
Dec 31 Vue.js
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
PHP5新特性: 更加面向对象化的PHP
2006/11/18 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
2014/07/30 PHP
字符串长度函数strlen和mb_strlen的区别示例介绍
2014/09/09 PHP
PHP移动文件指针ftell()、fseek()、rewind()函数总结
2014/11/18 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
一个基于jQuery的树型插件(OrangeTree)使用介绍
2012/05/03 Javascript
JS打开新窗口的2种方式
2013/04/18 Javascript
javascript获取设置div的高度和宽度兼容任何浏览器
2013/09/22 Javascript
js动态设置div的值下例子
2013/10/29 Javascript
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
js通过八个点 拖动改变div大小的实现方法
2014/03/05 Javascript
js创建表单元素并使用submit进行提交
2014/08/14 Javascript
javascript中的作用域和闭包详解
2016/01/13 Javascript
有关easyui-layout中的收缩层无法显示标题的解决办法
2016/05/10 Javascript
jquery if条件语句的写法
2016/05/19 Javascript
前端页面文件拖拽上传模块js代码示例
2017/05/19 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
使用D3.js+Vue实现一个简单的柱形图
2018/08/05 Javascript
基于vue中keep-alive缓存问题的解决方法
2018/09/21 Javascript
vue element动态渲染、移除表单并添加验证的实现
2019/01/16 Javascript
layui之table checkbox初始化时选中对应选项的方法
2019/09/02 Javascript
nginx配置域名后的二级目录访问不同项目的配置操作
2020/11/06 Javascript
[52:06]完美世界DOTA2联赛决赛日 Inki vs LBZS 第一场 11.08
2020/11/10 DOTA
Python3实现发送QQ邮件功能(html)
2017/12/15 Python
pycharm 批量修改变量名称的方法
2019/08/01 Python
Python 远程开关机的方法
2020/11/18 Python
科颜氏美国官网:Kiehl’s美国
2017/01/31 全球购物
无畏的旅行:Intrepid Travel
2017/12/20 全球购物
英国Boots旗下太阳镜网站:Boots Designer Sunglasses
2018/07/07 全球购物
致接力运动员广播稿
2014/02/17 职场文书
母亲节感恩寄语
2014/02/21 职场文书
人事任命书怎么写
2014/06/05 职场文书
房屋产权共有协议书范本
2014/11/03 职场文书
导游词之茶卡盐湖
2019/11/26 职场文书
js基于div丝滑实现贝塞尔曲线
2022/09/23 Javascript