深入浅出:了解深拷贝和浅拷贝

值传递:基本数据类型传递数据(数据发生改变的时候,另一个数据不会发生改变)
引用传递:引用数据类型传递数据,复制另一个引用数据类型的地址,所以当数据发生改变的时候,另一个引用数据类型的数据也会发生改变。因为他们的两个只想同一地址。
 1.浅拷贝:当一个对象复制另一个对象的数据后,当改变其中一个对象的数据后,另一个对象的数据也会发生改变,这就是浅拷贝;
 2.深拷贝:当一个对象复制另一个对象的数据后,当改变其中一个对象的数据后,另一个对象的数据不会发生改变,这就是深拷贝;
 (1).最简单的浅拷贝
var obj = { a: 1, b: 2, c: 3 };
var newObj = obj;
newObj. a = 10;
console. log( obj); //{a:10,b:2,c:3}
console. log( newObj); //{a:10,b:2,c:3};

(2).ES6对象的方法:Object.assign():第一个参数是目标对象,后面的参数都是源对象(需要拷贝的对象);返回值是合并后的对象。
例:当对象是多层的时候

 

var obj = { data: { a: 1, b: 2, c: 3 } };
var newObj = Object. assign({}, obj);
newObj. data. a = 10;
console. log( obj, newObj)
3、自己封装copy的方法
var obj = {
"data" : { 'a' : '1' },
"b" : "1",
"c" : "2"
}
function copy( obj) {
var newObj = {};
for ( var key in obj) {
newObj[ key] = obj[ key];
}
return newObj;
}
var newObj = copy( obj);
console. log( newObj) //{"data":{'a':'1'},"b":"1","c":"2"}
newObj. data. a = 10; //二层对象进行的是浅拷贝
newObj. b = 50; //一层对象进行生拷贝
console. log( obj, newObj) //{"data":{'a':'10'},"b":"1","c":"2"},{"data":{'a':'10'},"b":"50","c":"2"}
4、$.extend({},{})
var obj = { data: { a: 1, b: 2, c: 3 } };
var newObj = $. extend({}, obj);
newObj. data. a = 10;
console. log( obj, newObj)
深拷贝
1、Object.assign()
前提是对象只有一层
var obj = { a: 1, b: 2, c: 3 };
var newObj = Object. assign({}, obj);
newObj. a = 20;
console. log( obj, newObj)
2、$.extend()
当第一个参数是true的时候是深拷贝 当不传递的时候是浅拷贝
var obj = { data: { a: 1, b: 2, c: 3 } };
var newObj = $. extend( true, {}, obj);
newObj. data. a = 20;
console. log( obj);
console. log( newObj)
3、JSON.stringify;但目标对象有要求(非 undefined,function)
var obj = { data: { a: 1, b: 2, c: 3 } };
var newObj = JSON. parse( JSON. stringify( obj));
newObj. data. a = 20;
console. log( obj);
console. log( newObj)
缺点是函数不能被赋值
4.递归方法
function deepClone( initalObj, finalObj) {
var obj = finalObj || {};
for ( var i in initalObj) {
if ( typeof initalObj[ i] === 'object') {
obj[ i] = ( initalObj[ i]. constructor === Array) ? [] : {};
arguments. callee( initalObj[ i], obj[ i]);
} else {
obj[ i] = initalObj[ i];
}
}
return obj;
}
上述代码确实可以实现深拷贝。但是当遇到两个互相引用的对象,会出现死循环的情况。为了避免相互引用的对象导致死循环的情况,则应该在遍历的时候判断是否相互引用对象,如果是则退出循环。
改进版代码如下:

 

function deepClone( initalObj, finalObj) {
var obj = finalObj || {};
for ( var i in initalObj) {
var prop = initalObj[ i];

// 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if ( prop === obj) {
continue;
}

if ( typeof prop === 'object') {
obj[ i] = ( prop. constructor === Array) ? [] : {};
arguments. callee( prop, obj[ i]);
} else {
obj[ i] = prop;
}
}
return obj;
}
使用的时候这样写:
        var Doctor = deepCopy(Chinese);
        现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性:
         Chinese.birthPlaces = ['北京','上海','香港'];
          Doctor.birthPlaces.push('厦门');
        这时,父对象就不会受到影响了。
        alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
          alert(Chinese.birthPlaces); //北京, 上海, 香港
        目前,jQuery库使用的就是这种继承方法。

 

5.使用Object.create()方法;直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。

function deepClone( initalObj, finalObj) {
var obj = finalObj || {};
for ( var i in initalObj) {
var prop = initalObj[ i];

// 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
if ( prop === obj) {
continue;
}

if ( typeof prop === 'object') {
obj[ i] = ( prop. constructor === Array) ? [] : Object. create( prop);
} else {
obj[ i] = prop;
}
}
return obj;
}


 

转载于:https://www.cnblogs.com/yunshangwuyou/p/9602183.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值