Variables don't directly contain objects (including arrays), they contain references to those objects elsewhere in memory. So you start with:
+−−−−−−−−−−−−+
mt:Ref55162−−−−−−−−−−−>| (array) |
+−−−−−−−−−−−−+
| 0: "hola" |
| 1: "adios" |
+−−−−−−−−−−−−+
Then when you do const wm = mt;
, you're just copying the reference; both variables (constants) point to the same array:
mt:Ref55162−−−−−+
|
| +−−−−−−−−−−−−+
+−−−−−>| (array) |
| +−−−−−−−−−−−−+
| | 0: "hola" |
wm:Ref55162−−−−−+ | 1: "adios" |
+−−−−−−−−−−−−+
(That Ref55162 value is just for illustration; you never see the actual value of an object reference in JavaScript code.)
If you want to make a copy of an array, you have various options:
slice
: const wm = mt.slice();
Array.from
: const wm = Array.from(mt);
Spread notation: const wm = [...mt];
concat
: [].concat(mt)
Note that #2 - #4 in theory involve temporary objects, but if this code is in a performance-critical area, those temporary objects may get optimized away. #1 doesn't involve any temporary objects. (Okay, even for the last one, in theory the spec describes the creation of a lexical environment object for the call to slice
but in practice, implementations don't always have to literally create those objects and avoid it where possible.)
It may be worth pointing out that if you have an array that contains object references, then just like wd = mt
, the above all give you a new array containing copies of the references. So if you have:
const a = [{value: 1}, {value: 2}];
const b = a.slice();
...now a
and b
are different arrays, but both arrays contain references to the same two objects:
+−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−+
a:Ref14785−−−−−>| (array) | | |
+−−−−−−−−−−−−−+ \ +−−−−−−−−−−+ |
| 0: Ref55463 |−−−+−>| (object) | |
| 1: Ref16839 |−−+ +−−−−−−−−−−+ |
+−−−−−−−−−−−−−+ | | value: 1 | |
| +−−−−−−−−−−+ |
| |
\ +−−−−−−−−−−+ |
+−>| (object) | |
/ +−−−−−−−−−−+ |
| | value: 2 | |
| +−−−−−−−−−−+ |
+−−−−−−−−−−−−−+ | |
b:Ref98464−−−−−>| (array) | | |
+−−−−−−−−−−−−−+ | |
| 0: Ref55463 |−−|−−−−−−−−−−−−−−−−−+
| 1: Ref16839 |−−+
+−−−−−−−−−−−−−+
If you wanted to copy those objects, you'd have to do that on purpose, for instance:
const b = a.map(obj => ({...obj}));
map
calls a callback for each entry in an array and builds a new array from the return values; {...obj}
copies the own enumerable properties from an object into a new object.
Or if a
were an array of arrays, you might do:
const b = a.map(array => array.slice());
(This continues. If the inner object or array contains an object, reference, then...)
This question's answers may be useful if you want to copy all the way down (a "deep" copy): What is the most efficient way to deep clone an object in JavaScript?
Alternatively, if you want the array to be unmodifiable, you can use freeze
on it:
Object.freeze(mt);
Then you can't change it at all.