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方法用于对象的合并,将源对象 ...
随机推荐
- centos6.9下安装composer
1.下载composer curl -sS https://getcomposer.org/installer | php ps:如果出现php无法运行的情况,请先把PHP加入环境变量 2.移动或复制 ...
- Quartz使用总结(转发:http://www.cnblogs.com/drift-ice/p/3817269.html)
Quartz可以用来做什么? Quartz是一个任务调度框架.比如你遇到这样的问题 想每月25号,信用卡自动还款 想每年4月1日自己给当年暗恋女神发一封匿名贺卡 想每隔1小时,备份一下自己的爱情动作片 ...
- Way to OpenSource
@1:Follow any instructions in the readme and make sure that you can configure and run the project on ...
- LVS Nginx Haproxy对比
一般对负载均衡的使用是随着网站规模的提升根据不同的阶段来使用不同的技术. 具体的应用需求还得具体分析,如果是中小型的Web应用,比如日PV小于1000万,用Nginx就完全可以了: 如果机器不少,可以 ...
- JAVA中遍历Map和Set方法,取出map中所有的key
Java遍历Set集合 1.迭代器遍历: Set<String> set = new HashSet<String>(); Iterator<String> it ...
- python读写Excel文件--使用xlrd模块读取,xlwt模块写入
一.安装xlrd模块和xlwt模块 1. 下载xlrd模块和xlwt模块 到python官网http://pypi.python.org/pypi/xlrd下载模块.下载的文件例如:xlrd-0.9. ...
- uboot相关的几篇好文
http://www.eeworld.com.cn/mcu/2015/0727/article_21246.html http://blog.csdn.net/kernel_yx/article/de ...
- 2020年将热门的8大IT职业领域
近日,外媒梳理了未来5年内,也是就是2020年仍将受到热捧的八大科技领域,为IT从业者如何做好长远规划.有针对性地培养自身技能.又不偏离热门岗位提供了参考.(图片来自网易) 2020年将热门的8大IT ...
- 20145240 《Java程序设计》第六周学习总结
20145240 <Java程序设计>第六周学习总结 教材学习内容总结 InputStream与OutputStream 10.1.1串流设计的概念 Java将输入/输出抽象化为串流,数据 ...
- each方法的简单使用
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/stric ...