JavaScript对象拷贝与对象拷贝与Object.assign用法实例分析用法实例分析
本文实例讲述了JavaScript对象拷贝与Object.assign用法。分享给大家供大家参考,具体如下:
深拷贝与浅拷贝深拷贝与浅拷贝
在 JavaScript 中,对于基本数据类型(undefined、null、boolean、number、string)来说,在变量中存储的就是这个变量本
身的值,复制是对值的复制值的复制,不存在深浅之说。但C系语言的共同特点中有,存储引用类型(对象),实际中在变量里存的是
它的地址。因此对 JavaScript 中的复杂数据类型(object)来说,也会有浅拷贝和深拷贝的概念:浅拷贝指两个不同的变量存浅拷贝指两个不同的变量存
的是同一个对象的地址,即两个变量指向同一块内存区域;深拷贝则是重新分配了一块内存区域来存储复制后的对象,两个变的是同一个对象的地址,即两个变量指向同一块内存区域;深拷贝则是重新分配了一块内存区域来存储复制后的对象,两个变
量存的是真正的两个互不影响的变量。量存的是真正的两个互不影响的变量。
p.s. 有些资料认为浅拷贝是重新分配内存,并把原对象中的各个属性进行依次复制而不进行递归复制属性值是对象的情况,也浅拷贝是重新分配内存,并把原对象中的各个属性进行依次复制而不进行递归复制属性值是对象的情况,也
就是只复制对象的最外面一层就是只复制对象的最外面一层。本文将这种情况归于“深拷贝和浅拷贝的中间情况”,文中以“是否划分新的内存”为界限划分深
浅拷贝,这种划分方式与 C/C++、C#、Java 等C系语言保持概念一致。
浅拷贝在浅拷贝在JavaScript中的实现中的实现
浅拷贝在js中很简单,例如:
let objA = {
name: '对象A',
content: '我是A'
};
let copyA = objA;
console.log(objA.name); // ==> "对象A"
console.log(copyA.name); // ==> "对象A"
如此即得到了objA的一份浅拷贝copyA,由于指向的是同一个对象,因此在修改objA的同时也是修改了copyA,反之亦然。
Object.assign()
Object.assign(target, …sources) MDN上对该方法的描述是 将所有可枚举属性的值从一个或多个源对象复制到目标对将所有可枚举属性的值从一个或多个源对象复制到目标对
象象,String类型和 Symbol 类型的属性都会被拷贝, 并且该方法会忽略值为该方法会忽略值为 或者或者 undefined 的源对象的源对象。例如:
var o1 = { a: 1 };
var o2 = { [Symbol('foo')]: 2 };
var obj = Object.assign({}, o1, o2);
console.log(obj); // { a : 1, [Symbol("foo")]: 2 } (cf. bug 1207182 on Firefox)
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
Object.assign 的深拷贝与浅拷贝的深拷贝与浅拷贝
注意前面说的是可枚举属性,这是一个介于完全的深拷贝和完全的浅拷贝之间的方法:如果我们把它的第一个参数target设置
为一个空对象 {},同时保证剩余的源对象sources中的属性类型不包含引用类型,则该方法的返回值就是一个与源对象相同的
但并不在同一块内存空间另一个对象,即获得了源对象的深拷贝。但是,如果源对象的属性中包含某个对象,也就是这个属性
的值指向某个对象,就像下面这样:
var obj = {
name: 'obj name',
content: {
a: 1,
b: 2
}
};
则使用 Object.assign({}, obj) 时,返回的目标对象中的content属性与源对象obj中的content属性指向的同一块内存区域,即对obj
下的content属性进行了浅拷贝浅拷贝。因此针对深拷贝,需要使用其他方法,比如自己实现一个深拷贝的方法,或者使用
JSON.parse(JSON.stringify(obj)), 因为 Object.assign()拷贝的是属性值。
Object.assign 的属性覆盖的属性覆盖
如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性,因此可以用来
合并对象(常用的一个场景是使用reducers更新React应用的状态)。
var o1 = { a: 1, b: 1, c: 1 };
var o2 = { b: 2, c: 2 };
var o3 = { c: 3 };
var obj = Object.assign({}, o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
评论0