js对象的深度克隆
2016-11-05 12:12
288 查看
js对象的深度克隆
基本类型和引用类型的复制
对于复制相信大家都不陌生,复制了有两种情况:引用类型的复制与基本类型的复制。其中基本类型的复制:在变量对象上创建一个新值,然后将该值复制到新值分配的位置上去。这两个变量可以参与任何操作而不互相影响。且二者都存储在栈内存中。而对于引用类型的复制,传递的仅仅是一个指向原引用类型的的地址(类似指针的概念)。他是仅仅是对地址的引用,而非间接寻址。这两个变量参与任何操作都会互相影响,原对象存储于堆内存,复制后对象存储于栈内存中。
引用类型的深度克隆
这两天因为准备面试所以刷了一下题。遇到一个出镜率很高的boy:对象的深度克隆。本以为拿来网上别人写的答案理解一下就可以,但在运行代码时总会出现或多或少的问题。所以自己又花了半天时间调试出一个自己的clone。可能会有或多或少的情况没有考虑到,希望大家多多指点。参考案例
首先,我先放我参考的一个博友 u010599762(http://m.blog.csdn.net/article/details?id=40144017)的clone方法。{ var o; if(obj1.constructor==Object) { o = new obj1.constructor() ; } else { o = new obj1.constructor(obj1.valueOf()) } for(var key in obj1) { if(obj1[key]!=o[key]) { if(typeof obj1[key] =="object"&&obj1[key]!=null) o[key] = clone2(obj1[key]) ; else o[key] = obj1[key] ; } } return o ; }
测试用例:
function Obj1(){ this.a = 1 ; this.b = 2 ; this.view = { 'name':'zhangsan' }; } Obj1.prototype.arr = [1,2,3,4] ; var oNew = new Obj1(); var copy = clone2(oNew) ; copy.view = { age : 10 } ; console.log('copy:'+copy.view); console.log('oNew:'+oNew.view); var oNew2 = { name : 'pan', position : 'student' } var copy2 = clone2(oNew2); copy2.name = 'wang'; console.log(copy2.name);//'wang' console.log(oNew2.name);//'pan'
问题一
对于普通对象的克隆是没什么问题,但是对于数组的克隆处理的就有点问题了。在测试用例中Obj1.prototype.arr = [1,2,3,4] ; var oNew = new Obj1(); var copy = clone2(oNew) ;
我用firebug调试了一下:
发现会出现这样的问题:copy 的数组对象arr 被克隆成了[[1,2,3,4]]。这是由于o = new obj1.constructor(obj1.valueOf());将传入数组作为一个对象进行处理了。
问题二
而且对于以字面量形式生成的对象也没有解决。测试代码:
var oNew2 = { name : 'pan', position : 'student' } var copy2 = clone2(oNew2); console.log(copy2); console.log(oNew2);
修改过的代码
于是帮我把程序进行了修改:function clone2(obj1) { var o; if(obj1.constructor==Object){//当obj1为字面量形式生成对象情况。 o = new obj1.constructor() ; for(var key in obj1) { if(o[key] != obj1[key]) { if(typeof obj1[key] =="object"&&obj1[key]!=null) o[key] = clone2(obj1[key]) ; else o[key] = obj1[key] ; } } } else if(obj1.constructor == Array) { //obj1是数组时的情况 var array = []; obj1.forEach(function(value) { if(typeof(value) != "object") array.push(value);//数组元素为基本类型 else array.push(clone2(value));//数组元素为引用类型 }); o = array; } else {//以构造函数形式new出的对象 o = new obj1.constructor(obj1.valueOf()); //当obj1为内置对象时obj1.valueOf()的参数作用才真正使用。否则,这里传递的参数就不会被用到。 for(var key in obj1){ if(!obj1.hasOwnProperty(key)) { if(typeof obj1[key] =="object"&&obj1[key]!=null) o[key] = clone2(obj1[key]) ; else o[key] = obj1[key] ; } } } return o ; }
这里有一点需要注意。在处理字面量对象(obj1.constructor==Object)与构造函数对象时我们队对象本身属性的判断方式不同。
对于字面量对象:
if(o[key] != obj1[key])
对于构造函数对象:
if(!obj1.hasOwnProperty(key))
这里是用于处理字面量问题的。
自述
小白一枚,代码可能漏洞百出,大家不喜可提点一下,但勿喷,会打击伦家写博客的热情滴。。。。相关文章推荐
- JS对象简单、深度克隆(赋值与引用的区别)
- js 对象深度克隆
- JS学习30:对象简单、深度克隆(复制、Clone)
- js中对象深度克隆,以及ES6中的深度克隆的实现
- JS中 对象的深度克隆
- js对象简单、深度克隆(复制)
- JS对象深度克隆实例分析
- 【JavaScript代码实现三】JS对象的深度克隆
- js对象深度克隆
- ****ife 递归实现深度克隆(内含JS数据类型判断,对象遍历)****
- 深度克隆---js对象引用
- js-对象深度克隆方法
- js深度克隆对象(函数有待大神指正,,,)
- JS对象简单、深度克隆(赋值与引用的区别)
- JS对象深度克隆实现
- js对象的深度克隆!
- JS对象深度克隆
- js深度克隆对象
- js面试题:实现对象深度克隆(deepClone)的三种方案
- Js深度克隆对象(对象的属性含有对象数组)