1

Why when I pass childObject directly and change it, object.childObject stays the same. While passing object and changing object.childObject does change object.childObject outside the function.

In my head I always pass by reference, so if I change the value of what childObject points to in f_b(), shouldn't it also change it in object.childObject?

If I pass child object:

f_b(someObject) {
  someObject = {
    b: 2
  }

  console.log("childObject inside f_b is ", someObject)
}

f_a() {
  let object = {
    childObject: {
      a: 1
    }
  }

  this.f_b(object.childObject);

  console.log("childObject inside f_a is ", object.childObject)
}

f(a)

Running F(a) would output:

childObject inside f_b is {b: 2}
childObject inside f_a is {a:1}

If I pass parent object:

f_b(someObject) {
  someObject.childObject = {
    b: 2
  }
  
  console.log("childObject inside f_b is ", someObject)
}
f_a() {
  let object = {
    childObject: {
      a: 1
    }
  }

  this.f_b(object);

  console.log("childObject inside f_a is ", object.childObject)
}

Running F(a) would output:

childObject inside f_b is {b: 2}
childObject inside f_a is {b: 2}

Why doesn't the former output the same as the latter?

TG Person
  • 435
  • 4
  • 11
  • 1
    You... You aren't changing the object. You're basically doing `let a = 1; a = 2;` and asking "why is 1 not being changed into 2?" – Niet the Dark Absol Jun 08 '21 at 14:17
  • 1
    "*In my head I always pass by reference*" - no. [JavaScript does not have pass-by-reference](https://stackoverflow.com/q/518000/1048572). The `someObject` parameter always is a local variable. – Bergi Jun 08 '21 at 14:24

1 Answers1

3

When you pass object.childObject into the function (in the first sample), you pass a reference to the childObject value. In the function, you reassign the parameter to a new object, which is fine, but it will have no effect on the value of object.childObject because JavaScript is exclusively pass-by-value. The value of object.childObject is a reference to an object, and the function cannot change that.

The second piece of code explicitly updates the childObject property of the parent object, so that does what you expect. Because object values are references to an object, your function can change the "insides" of the passed-in object reference (so long as it isn't frozen and the property is writable).

In general, code like this:

function x(a) {
  a = 17;
}

var something = 1;
x(something);

can never change something. Your case can be simplified to this:

function x(a) {
  a = 17;
}

var something = { property: 1 };
x(something.property);

Similarly, the value of something.property cannot be changed by the reassignment inside the function x().

Pointy
  • 405,095
  • 59
  • 585
  • 614