数据的深浅拷贝和赋值

数据的深浅拷贝和赋值

1、赋值

  • 对于基本数据类型:赋值的话会直接在栈空间开辟一个内存空间,用来存储被复制过来的数据值。
  • 对于引用数据类型:赋值的话会直接在栈空间开辟一个内存空间,用来存储赋值数据对应的堆中的存储地址。
var userName = '闷倒驴';
var user = {userName:'闷倒驴',sex:'女',body:{weight:'50kg',height:'160'}}
// 赋值 
var userCopy = user;
user.sex = '男';
user.body.weight = '100斤';
console.log(user);
console.log(userCopy);

修改user的sex、body.weight的数据值后,user和userCopy地址不变,但是里面的数据值都会改变
在这里插入图片描述

在这里插入图片描述

2、 浅拷贝

2.1浅拷贝原理
  • 对于引用数据类型,栈堆都会开辟一个新的空间,用来存储数据,堆空间开辟一个新空间,用来存储从源数据那赋值过来的数据,那么新开的栈中存储的是新开堆中的内存地址。
  • 对于基本数据类型,同基本数据类型的赋值一样。
var user = {userName:'闷倒驴',sex:'女',body:{weight:'50kg',height:'160'}}
// 浅拷贝
var userCopy = Object.assign({}, user);
user.sex = '男';
user.body.weight = '100斤';

修改user里面的基本数据不会对userCopy里面的数据产生影响,而修改user里面的引用数据类型即上例中的body.weight会对userCopy里面的body.weight数据产生影响。
在这里插入图片描述
在这里插入图片描述
修改后
在这里插入图片描述

2.2 可以实现浅拷贝的方法
方法一 Object.assign()

Object.assign()方法可以把任意多个源对象自身可枚举的属性浅拷贝到目标对象,然后返回目标对象。

let obj1 = { person: { name: "kobe", age: 41 }, sports: 'basketball' };
let obj3 = {aaa:3333}
let obj2 = Object.assign({}, obj1,obj3);
obj2.person.name = "wade";
obj2.sports = 'football'
console.log(obj1); 
console.log(obj2)

在这里插入图片描述

方法二 函数库lodash的_.clone方法

该函数库也有提供_.clone用来做浅拷贝。

var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = _.clone(obj1);
console.log(obj2);
obj1.a = 0;
obj1.b.f.g = 1000;
console.log(obj1);
console.log(obj2);

在这里插入图片描述

方法三 展开运算符 (…)
let obj1 = { name: '王美丽', address: { x: 100, y: 100 } }
let obj2 = { ...obj1 }
obj1.address.x = 200;
obj1.name = '闷倒驴'
console.log('obj2', obj2)

在这里插入图片描述

方法四 Array.prototype.concat()
let arr = [1, 3, {
    username: '王美丽'
}];
let arr2 = arr.concat();
arr2[2].username = '闷倒驴';
console.log('arr',arr);
console.log('arr2',arr2);

在这里插入图片描述

方法五 Array.prototype.slice()
let arr = [1, 3, {
    username: ' 王美丽'
}];
let arr3 = arr.slice();
arr3[2].username = '闷倒驴'
console.log('arr:',arr); 
console.log('arr3:',arr3); 

在这里插入图片描述

3、深拷贝

3.1 深拷贝原理
  • 对于引用数据类型,栈和堆空间都会开辟一个内存空间,栈中存储堆中新开的内存地址,堆中存储的数据和源数据一样,但是二者没什么联系
var userName = '闷倒驴';
var user = { userName: '闷倒驴', sex: '女', body: { weight: '50kg', height: '160' } }
// 深拷贝
var userCopy = JSON.parse(JSON.stringify(user));
user.sex = '男';
user.body.weight = '100斤';
console.log(user);
console.log(userCopy);

在这里插入图片描述
在这里插入图片描述

3.2 实现深拷贝的方法
方法一 JSON.parse(JSON.stringify())
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        let arr = [1, 3, {
            username: '闷倒驴'
        }];
        let arr1 = JSON.parse(JSON.stringify(arr));
        arr1[2].username = '王美丽';
        console.log(arr, arr1)
    </script>
</body>

</html>

在这里插入图片描述
注意:使用该方法会有一个缺点,该方法虽然可以实现数组或对象的深拷贝,但是不能处理函数和正则,因为这两者基于JSON.stringify和JSON.parse处理后,得到的正则就不再是正则(变为空对象),得到的函数就不再是函数(变为null)了。

  • 函数:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        let arr = [1, 3, {
            username: '闷倒驴'
        },function(){
            var aa = 111111
        }];
        let arr1 = JSON.parse(JSON.stringify(arr));
        arr1[2].username = '王美丽';
        console.log(arr, arr1)
    </script>
</body>

</html>

在这里插入图片描述

  • 正则
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        let arr = [1, 3, {
            username: '闷倒驴'
        },new RegExp("ab+c")];
        let arr1 = JSON.parse(JSON.stringify(arr));
        arr1[2].username = '王美丽';
        console.log(arr, arr1)
    </script>
</body>

</html>

在这里插入图片描述

方法二 函数库lodash的_.cloneDeep方法
var _ = require('lodash');
var obj1 = {
    a: 1,
    b: { f: { g: 2 } },
    c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
obj1.b.f = '改变f属性';
console.log(obj1,obj2);// false
方法三 JQuery.extend()方法

使用该方法需要引入JQuery

// $.extend(deepCopy, target, object1, [objectN])//第一个参数为true,就是深拷贝

var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM();

var $ = jQuery = require('jquery')(window);
var obj1 = {
    a: 1,
    b: { f: { g: 1 } },
    c: [1, 2, 3]
};
var obj2 = $.extend(true, {}, obj1);
console.log(obj1.b.f === obj2.b.f); // false
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值