how to pass by value in JavaScript

1

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 little while ago I asked here how to pass values without being by reference, they told me to use Object.assing, but it still is not working, can someone help me how to change ob [0] .name without changing or?

    
asked by anonymous 23.03.2018 / 17:08

3 answers

5

The assign method makes a shallow copy, that is, it copies the attribute values that are from the object, but for 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 I could help would be to use:

var b = JSON.parse(JSON.stringify(a))
    
23.03.2018 / 17:22
3

One solution is to serialize the object and deserialize to 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 to explaining the reason for serializing / deserializing better:

The serialize transforms a stream object, in this case a JSON string, which will "break" the reference with the original object, and the deserialize transforms back into object, that reference, creating a new object

    
23.03.2018 / 17:22
1

What you need to do is make a Deep copy .

Unlike the Shallow copy or shallow copy (explained in prmottajr response) , 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 will copy the properties for 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>

Asalreadymentionedinotheranswers.Solutionserializinganddeserializing:

let a=[{nome:"oi"},{nome:"xau"}]
let b=JSON.parse(JSON.stringify(a))

b[0].nome=5

console.log(a,b)

Fonts :

23.03.2018 / 17:41