
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