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 相关文章推荐
如何在标题栏显示框架内页面的标题
Feb 03 Javascript
javascript Array.prototype.slice的使用示例
Nov 14 Javascript
jquery实现带渐变淡入淡出并向右依次展开的多级菜单效果实例
Aug 22 Javascript
Node.js中文件操作模块File System的详细介绍
Jan 05 Javascript
jquery请求servlet实现ajax异步请求的示例
Jun 03 jQuery
详解vue渲染函数render的使用
Dec 12 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
Jan 22 Javascript
[原创]微信小程序获取网络类型的方法示例
Mar 01 Javascript
vue.js实现图书管理功能
Sep 24 Javascript
Vue.js的模板语法详解
Feb 16 Javascript
在Vue.js中使用TypeScript的方法
Mar 19 Javascript
Vue router传递参数并解决刷新页面参数丢失问题
Dec 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 获取百度的热词数据的代码
2012/02/18 PHP
php使用Cookie实现和用户会话的方法
2015/01/21 PHP
PHP session垃圾回收机制实例分析
2019/06/28 PHP
不同Jquery版本引发的问题解决
2013/10/14 Javascript
jQuery实现下拉框左右选择的简单实例
2014/02/22 Javascript
js实现兼容性好的微软官网导航下拉菜单效果
2015/09/07 Javascript
6种javascript显示当前系统时间代码
2015/12/01 Javascript
javascript事件委托的用法及其好处简析
2016/04/04 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
2016/12/08 Javascript
基于angular-utils-ui-breadcrumbs使用心得(分享)
2017/11/03 Javascript
解决低版本的浏览器不支持es6的import问题
2018/03/09 Javascript
解析vue data不可以使用箭头函数问题
2018/07/03 Javascript
基于 jQuery 实现键盘事件监听控件
2019/04/04 jQuery
create-react-app中添加less支持的实现
2019/11/15 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
python使用fileinput模块实现逐行读取文件的方法
2015/04/29 Python
详解Python的Twisted框架中reactor事件管理器的用法
2016/05/25 Python
浅谈python的dataframe与series的创建方法
2018/11/12 Python
浅谈Pandas Series 和 Numpy array中的相同点
2019/06/28 Python
Django高并发负载均衡实现原理详解
2020/04/04 Python
Pandas对每个分组应用apply函数的实现
2020/12/13 Python
需要知道的CSS3动画技术
2010/01/01 HTML / CSS
使用canvas绘制贝塞尔曲线
2014/12/17 HTML / CSS
蒂芙尼澳大利亚官方网站:Tiffany&Co. Australia
2017/08/27 全球购物
印度在线购买电子产品网站:Croma
2020/01/02 全球购物
在C中是否有模拟继承等面向对象程序设计特性的好方法
2012/05/22 面试题
介绍一下HTTP、HTTPS和SSL
2012/12/16 面试题
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2016/01/06 面试题
艺术设计专业个人求职信
2013/09/21 职场文书
库房主管岗位职责
2013/12/31 职场文书
大学军训感言1000字
2014/02/25 职场文书
应急处置方案
2014/06/16 职场文书
校园广播站开场白
2015/06/01 职场文书
go 原生http web 服务跨域restful api的写法介绍
2021/04/27 Golang
php访问对象中的成员的实例方法
2021/11/17 PHP
十大冰系宝可梦排名,颜值最高的阿罗拉九尾,第三使用率第一
2022/03/18 日漫