-2

I've been using JavaScript for years and this one has me stumped. As I understood things, when defining a var, one of two things will happen:

  1. If the expression is a primitive, var is defined as a new instance of that primitive with no reference to the passed expression.
  2. If the expression is an object literal, a new object is created.
  3. If the expression is an existing object, var will reference the object and any future changes to the object will be reflected.

However, I've run into a situation where case 3 doesn't apply:

var obj = {body: {'a': 1, 'b': 2, 'c': 3}};

var ref = obj.body;
ref = JSON.stringify(ref);

console.log(typeof ref); // string
console.log(typeof obj.body); // object

Since ref is defined as the body property of obj, I thought redefining ref as a string also would affect obj.body. So what am I missing?

Danil Speransky
  • 29,891
  • 5
  • 68
  • 79
Cliff
  • 697
  • 8
  • 19
  • 1
    you overwrite the variable, it is not going to change what is in the object.... – epascarello Aug 21 '17 at 13:38
  • I think the confusion comes from the fact that `ref = ...` does not mutate the object it points to. If you mutated `ref` (by setting `ref.a = 5` for example) you would see the updates via both references. – Phylogenesis Aug 21 '17 at 13:47

3 Answers3

2

JSON.stringify is a method which takes an object and returns its string representation, it doesn't change anything. By doing ref = x you make ref point to another thing, it doesn't affect what was there before assignment.

Danil Speransky
  • 29,891
  • 5
  • 68
  • 79
  • I'm still confused. If `ref` references `obj.body`, and then I did `ref = 'foo'`, wouldn't `obj.body` be redefined as `'foo'`? – Cliff Aug 21 '17 at 13:41
0

That simply means, you are no more referencing obj.body.body and referencing to something else.

var ref = obj.body; 

//ref holding obj.body now any changes to ref will effect obj.body.

ref = JSON.stringify(ref);

//ref holding a String returned by `stringify()` now any changes to ref will effect obj.body.

You see ?? You just changing the ref with different values. Not really changing anything on obj

Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Primitives are immutable. If there’s a difference in how they would behave compared to objects, you can’t observe that, so forget all that stuff about copying. Let’s talk instead in terms of “things”! Objects and primitives are both things. When you assign a thing to a variable, you are not copying the thing.

var x = literally any value;
var y = x;

x and y are both variables that contain the same thing. If you change the thing, it doesn’t matter where you access it from in the future; the thing changed. If you change the thing the variable contains, the thing it contained before is not affected.

var z = some other value;
y = z;  // y now contains the same thing as z instead of the same thing as x
        // only variables changed, and the things did not

There are a lot of answers that talk about this in other terms but I enjoy technical language.

tl;dr: For all intents and purposes, the distinction between objects and primitives in JavaScript is not a useful one.

ts;iwrse: This article about Python applies to JavaScript just as much.

Ry-
  • 218,210
  • 55
  • 464
  • 476