js学习笔记:浅复制&深复制

对象复制,就是以一个对象为基础生成一个一模一样的对象。但是在javascript中,使用简单的赋值语句所实现的是原对象的一个引用,对其中任何一个对象属性方法的改变,都将会影响另一个的属性方法.

浅复制

仅仅复制原对象的各个属性,而不复制原对象属性中引用的其他对象,导致新对象和原对象的这些属性引用的是一个地址。
也就是所,假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。

  • 如果是数组的话,可以使用数组的一些方法,在不传参的时候可以达到浅拷贝的效果:
var arr = ['old', 1, true, null, undefined];

var newArr = arr.concat();
var newArr2 = arr.slice();
  • 针对普通对象:
function shadowCopy(src) {
  var dst = src instanceof Array?[]:{};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      dst[prop] = src[prop];
    }
  }
  return dst;
}
var obj = {
    a:2,
    b:{c:3}
};

var shadowObj = shadowCopy(obj);

shadowObj.b == obj.b;  //true

可以看到,对于浅复制,新对象和原对象引用的是同一个对象。

  • ES6增加的方法Object.assign()也可以用于对象的浅复制:
var copy = Object.assign({}, obj);

Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上。

深复制

在浅复制的基础上,把要复制的对象所引用的对象也都复制了一遍。因此要用递归来改进上面的浅复制。

function deepCopy(src){
    var dst = {};
    for(prop in src){
        if(src.hasOwnProperty(prop)){
            if(typeof src[prop] == "object"){
                dst[prop] = deepCopy(src[prop]);
            }else{
                dst[prop] = src[prop];
            }
        }
    }
    return dst;
}
var obj = {
    a:2,
    b:{
        c:3,
        d:{
            e:4
        }
    }
};

var deepObj = deepCopy(obj);

deepObj.b == obj.b;  //false
deepObj.b.d == obj.b.d;  //false

可以看到深复制不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。

要实现深复制还有许多其他的方法:

  • JSON方法
var cloneObj = JSON.parse(JSON.stringify(obj));
  • jQuery.extend()
jQuery.extend([deep], target, object1, [objectN])

此方法用于用一个或多个其他对象来扩展一个对象,返回被扩展的对象。

第一个deep参数则指定是深拷贝还是浅拷贝。若为true则为深拷贝。

  • 复制各类型的值
function clone(src){
    var target;
    if(typeof src != "object"){
        return src;
    }
    target = Array.isArray(src)?[]:{};
    for(var prop in src){
        if(Object.prototype.hasOwnProperty.call(src,prop)){
            target[prop] = clone(src[prop]);
        }
    }
    return target;
}

你可能感兴趣的:(面试,javascript)