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生成json的函数代码(可以用php的json_decode解码)
Jun 11 Javascript
关于IE BUG与字符串截取substr的解决办法
Apr 10 Javascript
JavaScript AJAX之惰性载入函数
Aug 27 Javascript
jQuery使用drag效果实现自由拖拽div
Jun 11 Javascript
JavaScript中通过提示框跳转页面的方法
Feb 14 Javascript
AngularJs Understanding the Model Component
Sep 02 Javascript
微信小程序 教程之数据绑定
Oct 18 Javascript
js判断一个字符串是以某个字符串开头的简单实例
Dec 27 Javascript
webpack热模块替换(HMR)/热更新的方法
Apr 05 Javascript
bootstrap 弹出框modal添加垂直方向滚轴效果
Jul 09 Javascript
微信小程序使用setData修改数组中单个对象的方法分析
Dec 30 Javascript
react项目如何使用iconfont的方法步骤
Mar 13 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防止网站被攻击的应急代码
2015/10/21 PHP
PHP模板引擎Smarty自定义变量调解器用法
2016/04/11 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
JS网络游戏-(模拟城市webgame)提供的一些例子下载
2007/10/14 Javascript
javascript验证上传文件的类型限制必须为某些格式
2013/11/14 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
2013/11/19 Javascript
jquery zTree异步加载简单实例讲解
2016/02/25 Javascript
多种方式实现js图片预览
2016/12/12 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
JavaScript轻松创建级联函数的方法示例
2017/02/10 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
Angularjs的键盘事件的绑定
2017/07/27 Javascript
微信小程序云开发之模拟后台增删改查
2019/05/16 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
原生JavaScript之es6中Class的用法分析
2020/02/23 Javascript
Python学习资料
2007/02/08 Python
python操作xml文件示例
2014/04/07 Python
python新手经常遇到的17个错误分析
2014/07/30 Python
numpy.delete删除一列或多列的方法
2018/04/03 Python
python实现NB-IoT模块远程控制
2018/06/20 Python
python requests 测试代理ip是否生效
2018/07/25 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
浅谈PYTHON 关于文件的操作
2019/03/19 Python
python 寻找离散序列极值点的方法
2019/07/10 Python
Python实现Singleton模式的方式详解
2019/08/08 Python
在pytorch 中计算精度、回归率、F1 score等指标的实例
2020/01/18 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
python 中关于pycharm选择运行环境的问题
2020/10/31 Python
html2canvas截图空白问题的解决
2020/03/24 HTML / CSS
JNI的定义
2012/11/25 面试题
深圳茁壮笔试题
2015/05/28 面试题
电厂职工自我鉴定
2014/02/20 职场文书
数学高效课堂实施方案
2014/03/29 职场文书
小学运动会口号
2014/06/07 职场文书
初中教师个人工作总结
2015/02/10 职场文书
人间正道是沧桑观后感
2015/06/15 职场文书