上一节所说到的extendCopy再深一层的对象属性是不能复制的,下面我们就学习另一个拷贝方法。
function deepCopy(p, c) { var c = c || {}; for (var i in p) { if (typeof p[i] === 'object') { c[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(p[i], c[i]); } else { c[i] = p[i]; } } return c; }
前几节我们说到了要注意引用复制,改变copy对象,也会改变初始的对象,而深度拷贝完全避免了这个问题。
来创建一个复杂的对象
var parent = { numbers: [1, 2, 3], letters: ['a', 'b', 'c'], obj: { prop: 1 }, bool: true };
让我们测试一下深度拷贝和extendCopy的区别
var mydeep = deepCopy(parent); var myshallow = extendCopy(parent); mydeep.numbers.push(4,5,6); mydeep.numbers;//[1,2,3,4,5,6] parent.nubmers;//[1,2,3] 不会影响初始的对象 myshallow.numbers.push(10);//4 myshallow.numbers;//[1,2,3,10] parent.numbers;//[1,2,3,10] //改变了初始的对象
深度拷贝的想法来自Jquery。。。
从上面的继承方法受到了启发。建议使用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; }
使用这个方法和extendCopy()一样。
var triangle = object(twoDee); triangle.name = 'Triangle'; triangle.getArea = function(){return this.side * this.height / 2;}; triangle.toString();// "shape, 2D shape, Triangle"
这个方法也是基于prototype的继承。因为把父对象作为子对象的prototype属性。