13

repl.it : https://repl.it/BuXR/3

var str = "abc";
var str2 = str.split(" ").join("").split("");
var tmp = str2;
console.log(str2);
// => ['a','b','c']
console.log(tmp.reverse());
// => ['c','b','a']
console.log(str2);
// => ['c','b','a']

My question is why str2 is being changed even though it is not being reversed?

This is very upsetting to me, but I have a guess as to why this is happening. The tmp is just a pointer to the original str2, and when I call reverse() on tmp, it actually reverses str2.

Even if that really is what's happening, I still feel like it is a very counterintuitive way for a language to work.

John Chen
  • 199
  • 7
  • 7
    possible duplicate of [Copying array by value in JavaScript](https://stackoverflow.com/questions/7486085/copying-array-by-value-in-javascript) – Bergi Mar 09 '16 at 05:09
  • 4
    It's not a pointer to `str2`, but a pointer to the same array that `str2` points to. – Bergi Mar 09 '16 at 05:10
  • Yes you are right. Thank you for the link. – John Chen Mar 09 '16 at 05:17
  • @NickSpriet `string` is *not* a reference type in JavaScript. `str2` is an *Array*, not a string. It's not a very good name for that variable. – Patrick Roberts Mar 09 '16 at 12:31
  • @JohnChen if this is counterintuitive to you, I recommend a language like MATLAB where pretty much everything is call-by-value. – Patrick Roberts Mar 09 '16 at 12:35
  • @PatrickRoberts Strings are exotic objects (like arrays), and are thus reference types. [See here](http://www.ecma-international.org/ecma-262/6.0/#sec-string-exotic-objects). – Dan Mar 09 '16 at 13:26
  • @DanPantry I see no indication in that documentation to suggest that exotic objects are "reference types". – Patrick Roberts Mar 09 '16 at 15:55
  • @PatrickRoberts in JavaScript, exotic objects are a type of object. All objects constructed by a constructor are reference types - this includes all types that are not primitive. You can see this [here](http://www.ecma-international.org/ecma-262/6.0/#sec-getvalue), where `GetValue` will return `V` early if the type of the inspected object is not a reference (i.e primitive). – Dan Mar 09 '16 at 16:39

4 Answers4

12

Your guess is right.

The tmp is just a pointer to the original str2, so whatever operations are performed on str2 it will be stored to memory and when you access tmp it find the reference to str2.

I have a guess as to why this is happening. The tmp is just a pointer to the original str2, and when I call reverse() on tmp, it actually reverses str2.

Hemant Metalia
  • 29,730
  • 18
  • 72
  • 91
11

2 Reasons why this is happening:

  • The reverse() method reverses an array in place, hence tmp is reversed: ref
  • The variable tmp and str2 are references to the same array instance, hence str2 also reversed.
Royal Pinto
  • 2,869
  • 8
  • 27
  • 39
5

My question is why str2 is being changed even though it is not being reversed?

Since the str2 and tmp are references which points to the same array. So whatever operation is done on tmp will be performed on string to which str2 is also pointing to.

If you want it to point it to another array then simply try

var tmp = [].concat(str2);
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
0

You need to create a new point on memory of the array:

Array.prototype.clone = function(){
    return JSON.parse(JSON.stringify(this));
};
var arr = [1, 2, 3];
var arr_clone = arr.clone();
arr_clone.reverse();
console.log(arr_clone);
// [3,2,1]
console.log(arr);
// [1,2,3]
cbertelegni
  • 423
  • 2
  • 11