js对象浅拷贝有解构赋值,assign2个方法吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js对象浅拷贝有解构赋值,assign2个方法吗?相关的知识,希望对你有一定的参考价值。
解构赋值、Object.assign都是对象浅拷贝。要深拷贝,需要自己实现或使用第三方库如 jQuery.extend、lodash等。 参考技术A 1、首先可以通过Object.assign来解决这个问题,很多人认为这个函数是用来深拷贝的。其实并不是,Object.assign只会拷贝所有的属性值到新的对象中,如果属性值是对象的话,拷贝的是地址,所以并不是深拷贝。
2、还可以通过展开运算符...来实现浅拷贝
let a = age: 1
let b = ...a
a.age = 2
console.log(b.age) // 1
ES6的解构赋值与深拷贝和浅拷贝
昨天工作之中,前端伙伴讨论到了解构赋值到底是浅拷贝还是深拷贝,今天梳理一下。
1、ES6的解构赋值,大家应该都清楚,就是可以快速取出数组或者对象中的值;具体使用情况如下:
const a = { name: ‘name‘, age: 18, marriage: false, } let { name, age, marriage} = a; console.log(name, age, marriage)
打印信息:name 18 false
2、明确一下深拷贝和浅拷贝的定义,或者说深拷贝和浅拷贝所应用于的数据类型。
深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型(number,string,null,undefined,boolean)都是深拷贝。
浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型(object)都是浅拷贝。
其实你只要理解透彻了这两句话就应该明白了解构赋值,甚至深拷贝的原理;
写两个例子,理解一下深拷贝和浅拷贝;
2.1 基本数据类型,直接用等号赋值,也都是深拷贝;
let a = 1; let b = a; b = 2; console.log(a,b);
打印出:1,2
b的数值改变并不会影响a,所以基本数据类型赋值就是深拷贝;
2.2 引用类型,直接用等号赋值,是浅拷贝;
let a = { name: ‘xiaoming‘ }; let b = a; b.name = ‘zhangsan‘; console.log(a)
打印:
发现a的数据被b改变,所以是浅拷贝,为什么数据会被改变呢?
因为他们引用的是同一个地址的数据!拷贝的时候并没有给b创造独立的内存,只是把a指向数据的 指针 拷贝给了b!(不做延伸,感兴趣的同学自行百度)
3、回到解构赋值,改一下最上面的例子。
const a = { name: ‘name‘, age: 18, marriage: false, } let { name, age, marriage} = a; name = ‘name1‘; age = 20; marriage = true; console.log(a)
打印:
发现a的数据并没有被改变,解构赋值好像是深拷贝啊?????
我们再改一下上面的例子看看:
const a = { name: ‘name‘, age: 18, marriage: false, addr: { province: ‘sichuan‘, city: ‘chengdu‘ } } let { name, age, marriage, addr } = a name = ‘myname‘ age = 26 marriage = true addr.province = ‘shanghai‘ addr.city = ‘shanghai‘ console.log(name, age, marriage, addr) console.log(a)
打印:
发现解构赋值出来的对象将原对象a中的addr的数据修改了,这样看还是浅拷贝;
总结:解构赋值,如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;
如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;
最终的结论就是:解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用);
4、最后我们再看一下深拷贝的本质:
深拷贝的实现方法:
function deepClone(source){ const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象 for(let keys in source){ // 遍历目标 if(source.hasOwnProperty(keys)){ if(source[keys] && typeof source[keys] === ‘object‘){ // 如果值是对象,就递归一下 targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); }else{ // 如果不是,就直接赋值 targetObj[keys] = source[keys]; } } } return targetObj; }
主要看这个:
它的本质还是将对象拆开为基本数据类型进行赋值。
以上是关于js对象浅拷贝有解构赋值,assign2个方法吗?的主要内容,如果未能解决你的问题,请参考以下文章