0

Function f3 accepts an array of simple objects, a, as parameter and returns an array whose items are copies of the items of array a

why when i do this statement b[0].a = 2; the value of a[0].a; change to

this is my code

<script type="text/javascript">
    function f3(obj= [{a: 1, b: 'str'}]) {
        let r = [];
        for (let prop of Object.values(obj)){
            r.push(prop);
        }
        return(r);
    }


    const a = [{a: 1, b: 'str'}];
    console.log(a[0]);// output {a: 1, b: "str"}

    const b = f3(a); 
    console.log(b[0]);// output {a: 1, b: "str"}
    console.log(b[0].a);// output 1 

    b[0].a = 2;

    console.log(a[0]);// output {a: 2, b: "str"}
    console.log(b[0]);// output {a: 2, b: "str"}
    console.log(a[0].a);// output 2
    console.log(b[0].a);// output 2

</script>
3
  • It's taking the array by reference, so when you change the value in b, it changes the value in a. Commented Dec 3, 2018 at 14:02
  • Aaah, I understand, so how can fix it without touch on the output statements !! Commented Dec 3, 2018 at 14:13
  • See answers below, they will help you. Commented Dec 3, 2018 at 14:29

2 Answers 2

1

Assuming the objects in your array are JSON compatible (all property values are primitives or nested arrays and objects), you can clone the array with json stringify/parse:

function f3(obj){
    return JSON.parse(JSON.stringify(obj));
}

Short. Simple. Works like a charm.

Sign up to request clarification or add additional context in comments.

2 Comments

Code that only works for some kind of inputs and breaks, or, worse, silently generates wrong results for others is hardly a "charm".
@georg, if you know your input is JSON then this is the simplest solution. Not every function should sanitize against any possible input.
1

Array and Object are stored by reference. So when you make change in any key of object or any index of Array, it will make effect on both variables because the reference is same.

In your case const a = [{a: 1, b: 'str'}]; and const b = f3(a); accessing the same reference. You are passing a object and returning same referenced object. Try it with returning new object.

You can do this by Object.assign() or new ES6 feature Rest operator.

check this link bellow - Rest Operator, Object.assign()

Thanks.

1 Comment

Careful here. Object.assign and the rest operator will not result in deep copies. It probably wouldn't solve the OPs issue. "For deep cloning, we need to use other alternatives because Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value." JSON.stringify/parse works MOST of the time. If you use symbols as keys, they get ignored/dropped, that sort of thing. but for most general use, it's the way to go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.