egg
, an object, mutates after the isBroken
property is added to it. Such objects (like egg
) we call mutable (that is, having the ability to mutate, change). const egg = { name: "Humpty Dumpty" }; egg.isBroken = false; console.log(egg); // { // name: "Humpty Dumpty", // isBroken: false // }
newEgg
in which an egg
object is written. Then it was necessary to change the name
property of newEgg
: const egg = { name: "Humpty Dumpty" }; const newEgg = egg; newEgg.name = "Errr ... Not Humpty Dumpty";
newEgg
(subject the object to a mutation), the egg
changes automatically. Did you know about this? console.log(egg); // { // name: "Errr ... Not Humpty Dumpty" // }
false
. console.log({} === {}); // false
egg
constant was assigned to the newEgg
constant, a reference to the same object referenced by the egg
constant was written to newEgg
. Since egg
and newEgg
refer to the same object, when newEgg
changes, egg
changes automatically. console.log(egg === newEgg); // true
String
, Number
, Boolean
, Null
, Undefined
, and Symbol
) are immutable. That is, you cannot change the structure of a primitive, you cannot add properties or methods to it. For example, when you try to add a new property to a primitive, absolutely nothing happens. const egg = "Humpty Dumpty"; egg.isBroken = false; console.log(egg); // Humpty Dumpty console.log(egg.isBroken); // undefined
const
keyword are immutable. However, it is not.const
keyword does not make what is written in a constant immutable. It only does not allow the constant to assign a new value. const myName = "Zell"; myName = "Triceratops"; // ERROR
const
, an object is defined, its internal structure may well be changed. In the example with the egg
object, even though egg
is a constant created using the keyword const
, this object does not protect against mutation. const egg = { name: "Humpty Dumpty" }; egg.isBroken = false; console.log(egg); // { // name: "Humpty Dumpty", // isBroken: false // }
Object.assign
method, which implements the operation of creating new objects by combining existing objects with assigning their properties to the resulting object.Object.assign
structure allows Object.assign
to combine two objects (or more objects), resulting in a single new object. You can use it like this: const newObject = Object.assign(object1, object2, object3, object4);
newObject
will contain properties from all objects passed to Object.assign
. const papayaBlender = { canBlendPapaya: true }; const mangoBlender = { canBlendMango: true }; const fruitBlender = Object.assign(papayaBlender, mangoBlender); console.log(fruitBlender); // { // canBlendPapaya: true, // canBlendMango: true // }
Object.assign
overwrites the property of an object that is in the list to the left. const smallCupWithEar = { volume: 300, hasEar: true }; const largeCup = { volume: 500 }; // volume , 300 500 const myIdealCup = Object.assign(smallCupWithEar, largeCup); console.log(myIdealCup); // { // volume: 500, // hasEar: true // }
Object.assign
, the first object in the argument list is subject to mutations. Others are not. console.log(smallCupWithEar); // { // volume: 500, // hasEar: true // } console.log(largeCup); // { // volume: 500 // }
Object.assign
object, Object.assign
can pass a new object in order to prevent the mutation of existing objects. However, the first object (empty) is still subject to change, but there is nothing to worry about, since the mutation does not affect anything important. const smallCupWithEar = { volume: 300, hasEar: true }; const largeCup = { volume: 500 }; // const myIdealCup = Object.assign({}, smallCupWithEar, largeCup);
myIdealCup.picture = "Mickey Mouse"; console.log(myIdealCup); // { // volume: 500, // hasEar: true, // picture: "Mickey Mouse" // } // smallCupWithEar console.log(smallCupWithEar); // { volume: 300, hasEar: true } // largeCup console.log(largeCup); // { volume: 500 }
Object.assign
is that it performs a shallow merge of objects - it copies properties directly from one object to another. At the same time, it also copies references to objects that are properties of the objects being processed. const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20, // } };
const loudPreset = { soundSettings: { volume: 100 } };
defaultSettings
and loudPreset
. const partyPreset = Object.assign({}, defaultSettings, loudPreset);
partyPreset
sounds weird. The volume is good, but no bass at all. When you explore partyPreset
, you are surprised to find that the bass settings are not here! console.log(partyPreset); // { // power: true, // soundSettings: { // volume: 100 // } // }
soundSettings
by reference. As with defaultSettings
, and loudPreset
have a soundSettings
object, the object that stands to the right in the Object.assign
arguments is copied to the new object.partyPreset
, loudPreset
mutates accordingly - as evidence that the link to soundSettings
from loudPreset
was copied to loudPreset
. partyPreset.soundSettings.bass = 50; console.log(loudPreset); // { // soundSettings: { // volume: 100, // bass: 50 // } // }
Object.assign
performs a surface merging of objects, in similar situations, when a new object is a combination of objects containing property objects, something else needs to be used. What? For example, the assignment
library.assignment
is the same as working with Object.assign
, except that it uses a different method name. // assignment const partyPreset = assignment({}, defaultSettings, loudPreset); console.log(partyPreset); // { // power: true, // soundSettings: { // volume: 100, // bass: 20 // } // }
partyPreset.soundSettings
, you will find that loudPreset
does not change. partyPreset.soundSettings.bass = 50; // loudPreset console.log(loudPreset); // { // soundSettings { // volume: 100 // } // }
assignment
library is just one of many tools that allow you to deeply merge objects. Other libraries, including lodash.assign and merge-options , can also help you with this. You can safely choose the one that you like best.Object.assign
. There is nothing wrong with this standard method if you know how to use it correctly.Object.assign
.Object.assign
when working with an object that has nested object properties, then you may have serious trouble.Object.freeze
method and the deep-freeze
library. These two tools do not produce errors, but do not allow objects to mutate.Object.freeze
method protects the object's own properties from changes. const egg = { name: "Humpty Dumpty", isBroken: false }; // "" egg Object.freeze(egg); // egg.isBroken = true; console.log(egg); // { name: "Humpty Dumpty", isBroken: false }
defaultSettings.soundSettings.base
. const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20 } }; Object.freeze(defaultSettings); defaultSettings.soundSettings.bass = 100; // soundSettings console.log(defaultSettings); // { // power: true, // soundSettings: { // volume: 50, // bass: 100 // } // }
Object.freeze
for all properties of the frozen object, which are objects. const defaultSettings = { power: true, soundSettings: { volume: 50, bass: 20 } }; // " " ( deep-freeze) deepFreeze(defaultSettings); // , defaultSettings.soundSettings.bass = 100; // soundSettings console.log(defaultSettings); // { // power: true, // soundSettings: { // volume: 50, // bass: 20 // } // }
a
changes from 11
to 100
. let a = 11; a = 100;
const egg = { name: "Humpty Dumpty" }; egg.isBroken = false;
Object.assign
and Object.freeze
.Object.assign
and Object.freeze
can protect only their own object properties from changes. If you want to protect against mutations and properties that are themselves objects, you will need libraries like assignment or deep-freeze .Source: https://habr.com/ru/post/346998/
All Articles