Object.assign()与深拷贝(一)
深拷贝与浅拷贝
所谓深拷贝与浅拷贝,是围绕引用类型变量的拷贝进行的讨论。
在ECMAScript中,变量分为基本类型和引用类型两种。其本质区别是不可变性,基本类型是不可变的,而引用类型是可变的。
所谓基本类型的不可变性,我们可以举个例子
let a = 1;
let b = 1;
a++;
a === 2;//true
b === 1;//true
声明一个变量a,并为其赋值1,这时内存中开辟出一片区域用来储存1。此时声明了一个变量b,也为b赋值1。当执行a++时,基本类型的不可变性就体现出来,a++的值应该为2,但是这个值并不会将原来储存1的那片内存覆盖掉,而是再开辟一片内存来存储2。所以对于这个1来讲,他是永远不可变的。
而对于引用变量则不同,因为其存储的是只想某个内存区域的地址,所以其修改时直接操作在内存上的,这就导致了深拷贝和浅拷贝问题的出现。
浅拷贝
let foo = {
x: 1,
y: -1
}
let bar = foo;
foo.x++;
foo.x === 2 //true
bar.x === 2 //true
这就是最简单的浅拷贝,其效果十分明显,对拷贝源的操作,会直接体现在拷贝目标上,因为这个赋值行为的本质是内存地址的赋值,所以他们指向了同一片内存区域。
浅拷贝十分容易,也十分常见,但却无法满足需求,假如我们需要获得与拷贝源完全相同,却又不会互相影响的对象,应该怎么办呢
Object.assign()
ES6为我们提供了一种十分好用的方法,Object.assign(target, ...source)方法
assign方法接受多个参数,第一个参数target为拷贝目标,剩余参数...source是拷贝源。此方法可以将...source中的属性复制到target中,同名属性会进行覆盖,并且在复制过程中实现了'伪'深拷贝
let foo = {
a: 1,
b: 2,
c: {
d: 1,
}
}
let bar = {};
Object.assign(bar, foo);
foo.a++;
foo.a === 2 //true
bar.a === 1 //true
乍一看,好像已经实现了深拷贝的效果,对foo.a进行的操作并没有体现在bar.a中,但是再往后看
foo.c.d++;
foo.c.d === 2 //true
bar.c.d === 1 //false
bar.c.d === 2 //true
Object.assign()的拷贝类型十分明显了,这是一种可以对非嵌套对象进行深拷贝的方法,如果对象中出现嵌套情况,那么其对被嵌套对象的行为就成了普通的浅拷贝.
如果真的想进行深拷贝,最简单粗暴地方式就是JSON操作.
JSON对象中包含两个方法, stringify()和parse(),前者可以将对象JSON化,而后者可以将JSON格式转换为对象.这是一种可以实现深拷贝的方法.
但这种方法的缺陷是会破坏原型链,并且无法拷贝属性值为function的属性
所以如果只是想单纯复制一个嵌套对象,可以使用此方法
let foo = {
a: 1,
b: {
c: 1
}
}
let bar = JSON.parse(JSON.stringify(foo));
总结为一句话:
对于普通对象(非嵌套对象)可采用Object.assign(target,source...)方法, 对于嵌套对象(没有属性类型为function的)采用JSON.parse.(JSON.stringify(objectA))
Object.assign()与深拷贝(一)的更多相关文章
- es6 Object.assign(target, ...sources)
Object.assign() 方法用于将所有可枚举属性(对象属性)的值从一个或多个源对象复制到目标对象.它将返回目标对象. 语法 Object.assign(target, ...sources) ...
- js - object.assign 以及浅、深拷贝
浅(引用)拷贝:共用同一内存地址,你改值我也变 譬如常用的对象赋值操作 深拷贝:深拷贝即创建新的内存地址保存值(互不影响) 譬如以下 const shallBasicCopy = obj => ...
- Object.assign()方法
对象的扩展 1.ES6中,对象的属性和方法可简写:对象的属性值可不写,前提是属性名已经声明: var name = "zhangsan"; "; var obj = { ...
- es6 Object.assign
ES6 Object.assign 一.基本用法 Object.assign方法用来将源对象(source)的所有可枚举属性,复制到目标对象(target).它至少需要两个对象作为参数,第一个参数是目 ...
- 浅谈Object.assign()
Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象.返回值为目标对象. 1 Object.assign 是 ES6 新添加的接口,主要的用途是用来合并多个 Ja ...
- Object.assign()解释整理
链接:https://blog.csdn.net/wang252949/article/details/79106160 语法 Object.assign(target, ...sources) 参数 ...
- ES6 对象的扩展 Object.assign()
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target). const target = { a: 1 }; const source1 ...
- [转]javascript之Object.assign()痛点
本文转自:http://blog.csdn.net/waiterwaiter/article/details/50267787 最近也一直会用javascript,然后中间使用的一些组件,如Echar ...
- es6 javascript对象方法Object.assign()
es6 javascript对象方法Object.assign() 2016年12月01日 16:42:34 阅读数:38583 1 基本用法 Object.assign方法用于对象的合并,将源对象 ...
随机推荐
- 我的Android进阶之旅------>Android横竖屏切换总结
在默认情况下当屏幕从竖评变到横屏时会触发 onConfigurationChanged 事件 在默认情况下会重新加载画面并显示和横屏一样的画面,这样会有2个问题, * 布局问题,在竖屏 显示的布局 ...
- Python获取位数
import platform platform.architecture()
- vue.js 拦截器
document.cookie = "mylogin=1";//1:登陆成功:保存登录状态 main.js router.beforeEach((to, from, next) = ...
- 理解java注解
@是java注解,即annotation. 注解功能可以理解为插件,是代码级别的插件,在类的方法上写:@XXX,就是在代码上插入了一个插件. Java注解是附加在代码中的一些元信息,用于一些工具在编译 ...
- .net全部版本的官方下载地址
https://technet.microsoft.com/zh-cn/5a4x27ek
- Latex排版全解(转)
Latex排版全解 http://blog.csdn.net/langb2014/article/details/51354238
- Simple Tips for Collection in Python
I believe that the following Python code is really not hard to understand. But I think we should use ...
- linux常用技巧(资料)
Linux中查看程序安装位置 如果是rpm的安装,用rpm -ql如果是一般安装 用 whereis 或者 find find /usr -name catalina.out======== 如何查看 ...
- Raspberry Pi开发之旅-发送邮件记录时间及IP
由于我使用树莓派的场景大多数是在没有显示器.只用terminal连接它的情况下,所以,它的IP地址有时会在重启之后变掉(DHCP的),导致我无法通过terminal连接上它.然后我又要很麻烦地登录路由 ...
- 蓝牙固件升级(OTA升级)原理设计
转:http://blog.csdn.net/yueqian_scut/article/details/50849033 固件空中升级(OTA)与固件二次引导的原理和设计 原创 2016年03月10日 ...