how to pass by value in JavaScript
I have the following Situation:
let a=[{nome:"oi"},{nome:"xau"}]
let b=Object.assign([], a)
b[0].nome=5
console.log(b) //[{nome:5},{nome:xau}]
console.log(a) //[{nome:5},{nome:xau}]
A short time ago I asked here how to pass values without being by reference, they told me to use the Object.assing, but still it is not working, someone can help me as I would to change the b [0].name without changing the a?
3 answers
The assign
method makes a shallow copy, that is, copies the values of attributes that are of the object, but whatever is reference it copies the value of the reference. In your example a
contains two references and so it is not working.
The suggestion I thought could help would be to use:
var b = JSON.parse(JSON.stringify(a))
One solution is to serialize the object and deserialize into a new one using JSON
, like this:
let b=JSON.parse(JSON.stringify(a))
let a=[{nome:"oi"},{nome:"xau"}]
let b=JSON.parse(JSON.stringify(a))
b[0].nome=5
console.log(b[0]) //[{nome:5},{nome:xau}]
console.log(a[0]) //[{nome:5},{nome:xau}]
EDIT : @Everson pointed out about better explaining the reason for serializing/deserializing:
The serialize transforms object into stream, in the case of a JSON string, which will "break" the reference with the original object, and the deserialize transforms again into object, that reference, creating a new object
What you need is to make a Deep copy.
Unlike Shallow copy or shallow copy(explained in the answer of prmottajr), you need a copy that is created without any reference to the original data, which is applicable for object arrays for example.
Solution creating a method:
(method that will create a new object and copy the properties to that object)
var a=[{nome:"oi"},{nome:"xau"}]
var b = Clonar(a);
b[0].nome=5;
console.log(a, b);
function Clonar(source) {
if (Object.prototype.toString.call(source) === '[object Array]') {
var clone = [];
for (var i=0; i<source.length; i++) {
clone[i] = Clonar(source[i]);
}
return clone;
} else if (typeof(source)=="object") {
var clone = {};
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
clone[prop] = Clonar(source[prop]);
}
}
return clone;
} else {
return source;
}
}
Solution with jquery :
var a=[{nome:"oi"},{nome:"xau"}]
var b = jQuery.extend(true, {}, a);
b[0].nome=5;
console.log(a, b);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
As mentioned in other answers. Solution serializing and deserializing:
let a=[{nome:"oi"},{nome:"xau"}]
let b=JSON.parse(JSON.stringify(a))
b[0].nome=5
console.log(a,b)
Sources :