对象的引用、浅拷贝、深拷贝

对象的引用

除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝。

将一个对象赋值给另外一个对象。

var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一个4
alert(a); // a变成了[1,2,3,4]  

自定义对象

var obj = {a:10};
var obj2 = obj;
obj2.a = 20; // obj2.a改变了,
alert(obj.a); // 20,obj的a跟着改变  

这就是由于对象类型直接赋值,只是将引用指向同一个地址,导致修改了obj会导致obj2也被修改。

浅拷贝

所以,我们需要封装一个函数,来对对象进行拷贝,通过for in 循环获取基本类型,赋值每一个基本类型,才能真正意义上的复制一个对象。

var obj = {a:10};
function copy(obj){
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = obj[attr];
    }
    return newobj;
}
var obj2 = copy(obj);
obj2.a = 20;
alert(obj.a); //10  

这样就解决了对象赋值的问题。

深拷贝

但是这里存在隐患,如果obj中,a的值不是10,而是一个对象,这样就会导致在for in中,将a这个对象的引用赋值为新对象,导致存在对象引用的问题。

var obj = {a:{b:10}};
function copy(obj){
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = obj[attr];
    }
    return newobj;
}
var obj2 = copy(obj);
obj2.a.b = 20;
alert(obj.a.b); //20  

因此,由于这个copy对象只是对第一层进行拷贝,无法拷贝深层的对象,这个copy为浅拷贝,我们需要通过递归,来拷贝深层的对象。将copy改造成递归即可。

var obj = {a:{b:10}};
function deepCopy(obj){
    if(typeof obj != 'object'){
        return obj;
    }
    var newobj = {};
    for ( var attr in obj) {
        newobj[attr] = deepCopy(obj[attr]);
    }
    return newobj;
}
var obj2 = deepCopy(obj);
obj2.a.b = 20;
alert(obj.a.b); //10  

自定义clone()方法来实现对象复制

下面的方法,是对象复制的基本想法。

Object.prototype.clone = function() {
  var copy = (this instanceof Array) ? [] : {};
  for (attr in this) {
    if (!obj.hasOwnProperty(attr)) continue;
    copy[attr] = (typeof this[i] == "object")?obj[attr].clone():obj[attr];
  } 
  return copy;
};


a = {k1:1, k2:2, k3:3};
b = a.clone();

下面的例子则考虑的更全面些,适用于大部分对象的深度复制(Deep Copy)。

function clone(obj) {
    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, var len = obj.length; i < len; ++i) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }
    // Handle Object
    if (obj instanceof Object) {
        var copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值