标签:
我们知道当对象拷贝时,实际上拷贝的只是该对象在内存中的位置指针,也就是说,如果我们修改了拷贝的对象,就等同于修改了原对象。
深拷贝与浅拷贝原理基本相同,只是在遇到一个对象引用性的属性时,我们需要再次调用深拷贝的函数:
function deepCopy(p, c){ c = c || {}; for(var i in p){ if(p.hasOwnProperty(i)){ if(typeof p[i] === ‘Object‘){ c[i] = Array.isArray(p[i]) ? [] : {}; deepCopy(p[i], c[i]); }else{ c[i] = p[i] } } } return c; }
我们创建一个对象,该对象包括数组和子对象:
var parent = { number: [1,2,3], letter: [‘a‘, ‘b‘, ‘c‘]; obj: { prop: 1 }, bool: true }
下面是之前的浅拷贝:
function extendCopy(parent){ var child = {}; for(var i in parent){ child[i] = parent[i]; } child.usber = parent; return child; }
我们用浅拷贝和深拷贝分别试一下:
var mydeep = deepCopy(parent); var myshallow = extendCopy(parent); mydeep.number.push(4,5,6); mydeep.number; // [1,2,3,4,5,6] parent.number; // [1,2,3] myshallow .number.push(10); myshallow .number; // [1,2,3,10] parent.number; // [1,2,3,10]
在使用深拷贝的时候要注意两点:
1. 在拷贝每个属性之前,建议使用hasOwnPrototype()来确认不会误拷贝不需要的继承属性。
2. 由于区分Array对象和普通对象Object相当繁琐,所以ES5实现了Array.isArray()函数。
if(Array.isArray !== ‘function‘){ Array.isArray = function(candidate){ return Object.prototype.toString.call(candidate) === ‘[Object Array]‘; } }
我们可以用object()来接收父对象,并返回一个以该对象为原型的新对象。
function object(o){ function F(){}; F.prototype = o; return new F(); }
如果我们要访问uber属性,可以继续:
function object(o){ var n; function F(){}; F.prototype = o; n = new F(); n.uber = o; return n; }
这个函数的使用与浅拷贝基本相同:
var a = object(o); o.name = ‘Anna‘;
这种模式也被称作原型继承,因为我们在这里将父对象设置成为了子对象的原型。javascript里更名为Object.create()。
var b = Object.create(a);
标签:
原文地址:http://www.cnblogs.com/beyond-succeed/p/5841177.html