1.Description Object.assign
_
Object.assign()
Method copies all enumerable (Object.propertyIsEnumerable()
returns true) own (Object.hasOwnProperty()
returns true) properties from one or more source objects to the target object, returning the modified object
1.1 Grammar
Object.assign(target, ...sources) // 返回合并后的target的对象
target
The target object, the object that receives the properties of the source object, is also the modified return value
source
The source object containing the properties to be merged.
2.Application Object.assign
_
2.1 Basic example
let target = {
a: 1 };
let source = {
b: 1, c: 1 };
const final = Object.assign(target, source);
console.log(final); // {a: 1, b: 1, c: 1}
// 我们输出target 看看
console.log(target); // {a: 1, b: 1, c: 1}
It is found that the target object has also changed. How to avoid this? deep copy
let target = {
a: 1 };
let source = {
b: 1, c: 1 };
const final = Object.assign(JSON.parse(JSON.stringify(target)), source);
console.log(final);// {a: 1, b: 1, c: 1}
console.log(target);// {a: 1} 这样就不会改变target了
2.2 When the same attributes exist in the merged objects
// 一个 source 时
let target = {
a: 1 };
let source = {
a: 100, b: 1, c: 1 };
const final = Object.assign(target, source);
console.log(final); // {a: 100, b: 1, c: 1}
// 两个source 时
let target = {
a: 1 };
let source = {
a: 100, b: 1, c: 1 };
let source1 = {
c: 100, d: 1 };
const final = Object.assign(target, source, source1);
console.log(final); // {a: 100, b: 1, c: 100, d: 1}
It can be found that the properties will be overwritten by other objects with the same properties in subsequent parameters.
2.3 Assignment reference problem
let source = {
a: 1,
b: {
c: 1,
},
};
const final = Object.assign({
}, source);
console.log(final); // { a: 1, b: { c: 1 } }
console.log(source);// { a: 1, b: { c: 1 } }
source.a = 2;
console.log(final);// { a: 1, b: { c: 1 } } 不变
console.log(source);// { a: 2, b: { c: 1 } } 变了
source.b.c = 2;
console.log(final); // { a: 1, b: { c: 2 } } 变了
console.log(source);// { a: 2, b: { c: 2 } } 变了
It can be found that the source object is a reference to an object, and it only copies its reference value. If the source object embeds an object and its value is changed in the source object, the merged value will also change.
How to avoid it? JSON.parse(JSON.stringify(Object.assign({}, source))
Just adopt it
2.4 Exceptions will interrupt subsequent copy tasks
let target = Object.defineProperty({
}, 'a', {
value: 1,
writable: false, // 不可写
});
try {
Object.assign(target, {
b: 1 }, {
a: 3 }, {
c: 1 });
} catch (e) {
console.log(e);
}
console.log(target.b); // 1
console.log(target.a); // 1
console.log(target.c); // undefined
If an error occurs during assignment, for example if the property is not writable, this will be thrown
TypeError
; if any properties were added before the exception was thrown,target
the object will be modified
2.5 Object.assign()
will not throw an error when source
the object value is null
orundefined
const final = Object.assign({
}, {
a: 1 }, undefined, {
b: 1 }, null);
console.log(final); // {a: 1, b: 1}
2.6 Properties and non-enumerable properties on the prototype chain cannot be copied
//摘自MDN
const obj = Object.create(
{
foo: 1 },
{
// foo 在obj的原型链上
bar: {
value: 2, // bar 是一个不可枚举属性
},
baz: {
value: 3,
enumerable: true, // baz 是一个枚举属性
},
}
);
const copy = Object.assign({
}, obj);
console.log(copy); // { baz: 3 }
2.7 Basic types will be packaged as objects
const obj = Object.assign({
}, 'happy');
console.log(obj); // {0: 'h', 1: 'a', 2: 'p', 3: 'p', 4: 'y'}
const obj = Object.assign({
}, 'happy', 'good', true, 10);
console.log(obj); // {0: 'g', 1: 'o', 2: 'o', 3: 'd', 4: 'y'} 注意与上面输出的前四个区别
Note: Only strings can have their own enumerable properties.
2.8 Copy accessor
// 摘自MDN
const obj = {
foo: 1,
get bar() {
return 2;
}
};
let copy = Object.assign({
}, obj);
console.log(copy); // { foo: 1, bar: 2 }
// 这是一个复制完整描述符的赋值函数
function completeAssign(target, ...sources) {
sources.forEach(source => {
let descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {
});
// 默认情况下,对象,也分配可枚举符号的副本
Object.getOwnPropertySymbols(source).forEach(sym => {
let descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(target, descriptors);
});
return target;
}
copy = completeAssign({
}, obj);
console.log(copy); // { foo:1, get bar() { return 2 } }
3. Ending
Refer to
the first day of MDN to review a JS method every day: Object.assign method