The whole point is that in Javascript all objects are assigned by reference without exceptions, this means that no matter how many variables you assign an object, it will always remain in memory in the singular.
var a = {prop: 1} var b = a; var c = b; (c===b&&b===a&&c===a) // true
As long as at least one variable refers to an object, it continues to exist. When the last variable referring to an object is deleted, the object itself is also deleted.
var a = {prop: 1}; var b = a; a.prop = 2; delete a; (b.prop===2); // true
In javascript, there is no operator that allows you to make a copy of an object, so copying objects in Javascript comes down to creating a new one with exactly the same properties as the first one.
var a = {prop: 1}; var b = {}; b.prop = a.prop;
However, it is necessary to take into account the fact that the property of an object may contain another object, which will also be passed by reference, in the case of assignment, so the following example will create a wrong clone:
var a = { prop: { sub: 1 } } var b = {}; b.prop = a.prop;
Because the sub property will be the same for both objects.
a.prop.sub = 2; (b.prop.sub===1) // False
Therefore, when creating a copy of an object, it is necessary to check whether its properties are not objects, and in this case, perform the same operation with them as we turned with a and b.
In general, the function of creating a clone of an object will look like this:
function makeClone(obj) { let clone = {}; // Создаем новый пустой объект for (let prop in obj) { // Перебираем все свойства копируемого объекта if (obj.hasOwnProperty(prop)) { // Только собственные свойства if ("object"===typeof obj[prop]) // Если свойство так же объект clone[prop] = makeClone(obj[prop]); // Делаем клон свойства else clone[prop] = obj[prop]; // Или же просто копируем значение } } return clone; }
However, this function is not universal and will not work correctly in all cases, since in Javascript, in addition to simple objects, there are also built-in objects and objects created from prototypes that can no longer just be taken and copied. These are instances of Image, Date, HTMLElement, custom classes, etc. In addition, there are cases when nested properties contain references to objects that indirectly return us to ourselves. For example:
var a = {}, b = {prop: a}; a.prop = b;
If you run the makeClone function for variable a, then the clone creation process will continue indefinitely, which will cause "Maximum call stack size exceeded". So there are so many nuances of cloning an object, so it’s better not to reinvent the wheel, but to use ready-made solutions such as jQuery.extend:
var a = {prop: 1}; var clone = jQuery.extend(true, {}, a);
In addition, stand-alone analogues of this function can be found on npmjs.
PS: About Object.assign - this is an experimental method and so far it is not supported by browsers, and it seems that babel without special plug-ins also does not perceive it.
ES6
in general, you can:var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
var obj = { a: 1 }; var copy = Object.assign({}, obj); console.log(copy); // { a: 1 }
developer.mozilla.org/ru/docs/Web/JavaScript/Reference/… - Aleksey Shimansky