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下的节点属性和操作小结
May 14 Javascript
javascript dom 操作详解 js加强
Jul 13 Javascript
javascript for循环从入门到偏门(效率优化+奇特用法)
Aug 01 Javascript
关于火狐(firefox)及ie下event获取的两种方法
Dec 27 Javascript
jquery ajax方式直接提交整个表单核心代码
Aug 15 Javascript
动态加载脚本提升javascript性能
Feb 24 Javascript
莱鸟介绍window.print()方法
Jan 06 Javascript
javascript关于继承解析
May 10 Javascript
js添加绑定事件的方法
May 15 Javascript
微信小程序用户拒绝授权的处理方法详解
Sep 20 Javascript
详解Vue之事件处理
Jul 10 Javascript
Vue+TypeScript中处理computed方式
Apr 02 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
PHP 计算代码执行耗时的代码修正网上普遍错误
2011/05/14 PHP
Discuz批量替换帖子内容的方法(使用SQL更新数据库)
2014/06/23 PHP
关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析
2016/01/08 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
2016/09/22 PHP
php 遍历目录,生成目录下每个文件的md5值并写入到结果文件中
2016/12/12 PHP
laravel与thinkphp之间的区别与优缺点
2021/03/02 PHP
js模仿jquery的写法示例代码
2013/06/16 Javascript
JavaScript获取元素尺寸和大小操作总结
2015/02/27 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
js a标签点击事件
2017/03/30 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
create-react-app 修改为多入口编译的方法
2018/08/01 Javascript
JavaScript实现新年倒计时效果
2018/11/17 Javascript
小程序实现授权登陆的解决方案
2018/12/02 Javascript
jQuery实现全选、反选和不选功能的方法详解
2019/12/04 jQuery
node 版本切换的实现
2020/02/02 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
详解Python正则表达式re模块
2019/03/19 Python
TensorFlow实现从txt文件读取数据
2020/02/05 Python
Python使用socket_TCP实现小文件下载功能
2020/10/09 Python
基于CSS3实现的漂亮Menu菜单效果代码
2015/09/10 HTML / CSS
HTML中fieldset标签概述及使用方法
2013/02/01 HTML / CSS
CK美国官网:Calvin Klein
2016/08/26 全球购物
数控专业毕业生求职信范文
2013/09/21 职场文书
生物科学系大学生的自我评价
2013/12/20 职场文书
行政部总经理岗位职责
2014/01/04 职场文书
幼儿园教研活动方案
2014/01/19 职场文书
英语教师自荐信
2014/05/26 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
环保守法证明
2015/06/24 职场文书
2015年暑期社会实践总结
2015/07/13 职场文书
学校教代会开幕词
2016/03/04 职场文书
详解Nginx 工作原理
2021/03/31 Servers
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android