0

In the code below, I expected that the result of the 3 logs would be the same.

But they are not.

var m = (function () {
  var arr = [
    {a: 1, b: 2}, 
    {c: 3, d: 4}
  ];

  return {
    getArr: function () {
      return arr;
    }
  };
})();

var myArr = m.getArr();

console.log(myArr);

myArr.pop();

console.log(m.getArr());

What is the best way to ensure that the array is not passed as a reference?

Use return arr.map()?

2
  • You can use return arr.slice() - however be aware that this would only be a shallow copy and you can still run into issues. Commented Sep 11, 2018 at 19:23
  • 1
    In Javascript, all objects are effectively "passed by reference". (This isn't strictly true, but is an easy way to think of it.) Arrays are objects too, so this is why this happens. Note that primitive values (strings, numbers, booleans) are always "passed by value" instead. This question may be useful for further explanation Commented Sep 11, 2018 at 19:37

2 Answers 2

5

JSON.parse(JSON.stringify(arr)) will give you a deep copy of an object or array.

var m = (function () {
  var arr = [
    {a: 1, b: 2}, 
    {c: 3, d: 4}
  ];

  return {
    getArr: function () {
      return JSON.parse(JSON.stringify(arr));
    }
  };
})();

var myArr = m.getArr();

console.log(myArr);

myArr.pop();

console.log(m.getArr());

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

1 Comment

While it works in most cases, a few things should definitely be brought to the attention of anyone using this method: 1. It only works on JSON-serializable content (that is, your array and objects cannot contain functions/methods, nor Infinity, null, or undefined). 2. It will convert date values to string. 3. It is very inefficient. That said, if your array is small (relatively speaking) and consists of only primitives and/or objects that consist of only primitives (string/number/boolean), this method will work perfectly fine.
1
var m = (function () {
  var arr = [
    {a: 1, b: 2}, 
    {c: 3, d: 4}
  ];

  return {
    getArr: function () {
      return Array.from(arr);
    }
  };
})();

Ensure that the closure returns a copy of the arr.

1 Comment

This also returns a shallow copy, so if the array has multiple layers of depth, you could still run into problems using Array.from

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.