Object.assign
A method for merging the object, the source object (source) of all enumerated attribute, copied to the target object (target).
const target = { a: 1 }; const source1 = { b: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
Object.assign
The first parameter is the target object's method, the source object parameters are behind.
Note that if the source object and the target object has attributes with the same name, or a plurality of source objects of the same name attribute, after the attribute overwrite the previous attribute.
const target = { a: 1, b: 1 }; const source1 = { b: 2, c: 2 }; const source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
If only one parameter, Object.assign
will return directly to the parameter.
const obj = {a: 1}; Object.assign(obj) === obj // true
If this parameter is not an object, it will turn into the first object and then returns.
typeof Object.assign(2) // "object"
Because undefined
, and null
not turn into an object, so if they are used as parameters, the error is reported.
Object.assign(undefined) // 报错 Object.assign(null) // 报错
If the non-object appears in a position of the source object (ie non-first parameter), then the processing rules are different. First, these parameters will turn into an object, if you can not turn into an object, will be skipped. This means that if undefined
and null
not in the first parameter, the error will not.
let obj = {a: 1}; Object.assign(obj, undefined) === obj // true Object.assign(obj, null) === obj // true
Values (i.e., values, and Boolean string) of other types is not the first parameter is not given. However, in addition to an array of strings, copied into the target object, other values will not be effective.
const v1 = 'abc';
const v2 = true; const v3 = 10; const obj = Object.assign({}, v1, v2, v3); console.log(obj); // { "0": "a", "1": "b", "2": "c" }
In the above code, v1
, v2
, v3
respectively, strings, Boolean values, and results only for strings into the target object (in the form of an array of characters), the numerical and Boolean values are ignored. This is because only the string wrapped object, will produce enumerable property.
Object(true) // {[[PrimitiveValue]]: true} Object(10) // {[[PrimitiveValue]]: 10} Object('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
In the above code, boolean, numeric, string, and transfected into a corresponding object to be wrapped, to their original values can be seen in the properties inside the package object [[PrimitiveValue]]
above, this property will not be Object.assign
copied. Wrapper object only strings, will have real meaning enumerable properties, those properties will be copied.
Object.assign
Copies of property is limited, only a copy of their own property of the source object (not copy inherited attributes), nor copy can not be enumerated attributes ( enumerable: false
).
Object.assign({b: 'c'}, Object.defineProperty({}, 'invisible', { enumerable: false, value: 'hello' }) ) // { b: 'c' }
In the above code, Object.assign
the object to copy only a non-enumerated attribute invisible
, this property has not been copied into.
Properties named Symbol values, will be Object.assign
a copy.
Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' }) // { a: 'b', Symbol(c): 'd' }
important point
(1) shallow copy
Object.assign
The method is practiced shallow copy, rather than a deep copy. That is, the value of a property if the source object is an object, then get a copy of the target object is a reference to the object.
const obj1 = {a: {b: 1}}; const obj2 = Object.assign({}, obj1); obj1.a.b = 2; obj2.a.b // 2
In the above code, the source object obj1
of the a
value of the attribute is an object, Object.assign
the copy obtained is a reference to the object. Any change in this object, will be reflected in the destination object.
(2) replacement of the same name attribute
For this nested object, the event attribute of the same name, Object.assign
the processing method is to replace, rather than adding.
const target = { a: { b: 'c', d: 'e' } } const source = { a: { b: 'hello' } } Object.assign(target, source) // { a: { b: 'hello' } }
The above code, target
object a
attributes are source
object a
properties of the entire replaced, while not get { a: { b: 'hello', d: 'e' } }
results. This is usually not the developers want, need special care.
Some libraries offer Object.assign
customized versions (such as Lodash of the _.defaultsDeep
method) can be obtained with deep copies.
(3) processing array
Object.assign
It can be used to handle an array, but the array will treated as objects.
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3]
In the above code, Object.assign
the array as an object property named 0,1,2, the source array property 0 4
covered 0 properties of the target array 1
.
Process (4) the value of the function
Object.assign
Copy only values, if you want to copy the value is a function of the value, then evaluated and then copied.
const source = {
get foo() { return 1 } }; const target = {}; Object.assign(target, source) // { foo: 1 }
The above code, source
object foo
attribute value is a function that Object.assign
does not copy the values of the function, only later to get the value, copy this value in the past.
Common uses
Object.assign
There are many ways useful.
(1) was added for objects
class Point {
constructor(x, y) { Object.assign(this, {x, y}); } }
By the above process Object.assign
method, the x
properties and y
add attributes to Point
the object class instance.
(2) a method of adding an object
Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· } }); // 等同于下面的写法 SomeClass.prototype.someMethod = function (arg1, arg2) { ··· }; SomeClass.prototype.anotherMethod = function () { ··· };
The above code uses a simple representation of object properties, the two functions directly in braces, then use the assign
method to the SomeClass.prototype
being.
(3) Cloning of the object
function clone(origin) { return Object.assign({}, origin); }
The above object is copied to the original code is an empty object, get a clone of the original object.
However, this method clones, only clone of the original object values itself, it can not be cloned inherited value. If you want to keep the inheritance chain, the following code can be used.
function clone(origin) { let originProto = Object.getPrototypeOf(origin); return Object.assign(Object.create(originProto), origin); }
(4) combining a plurality of objects
Combine multiple objects to an object.
const merge = (target, ...sources) => Object.assign(target, ...sources);
If you want to consolidate to return a new object, you can rewrite the above function, an empty object to the merger.
const merge = (...sources) => Object.assign({}, ...sources);
(5) specified for the attribute default values
const DEFAULTS = {
logLevel: 0, outputFormat: 'html' }; function processContent(options) { options = Object.assign({}, DEFAULTS, options); console.log(options); // ... }
The above code, DEFAULTS
the object is the default options
object is a user-supplied parameters. Object.assign
The methods DEFAULTS
and options
combined into a new object if both have the same name attribute, option
attribute value overrides the DEFAULTS
attribute values.
Note that, due to the presence of shallow copy problems, DEFAULTS
objects and options
all attributes of objects, preferably type are simple, do not point to another object. Otherwise, DEFAULTS
the properties of the object is likely to be ineffective.
const DEFAULTS = {
url: { host: 'example.com', port: 7070 }, }; processContent({ url: {port: 8000} }) // { // url: {port: 8000} // }
The original intent of the code above is url.port
changed to 8000, url.host
remain unchanged. The actual result is options.url
overwritten DEFAULTS.url
, it url.host
does not exist.
Author: poor old guy handsome drop
link: https: //www.jianshu.com/p/d5f572dd3776
Source: Jane books
are copyrighted by the author. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.