javascript pass object as reference

JavascriptVariablesObjectReferencePass by-Reference

Javascript Problem Overview


i have a object, which is getting passed in many different functions inside a function. these functions may or may not change the value of the object, but if they do change it, then i would like to get the latest changes on object.

following is what im trying to do:

var ob = {text: 'this is me', name: 'john'}

function (object) {

     changeObject(object);
     customObjectChanger(object);
     callback = function (object) {
          object.text = 'new text';
     }
     
     callback(object);

     // object value here should be object{text: 'new text', name: 'john'};    
}

Javascript Solutions


Solution 1 - Javascript

In JavaScript objects are always passed by copy-reference. I'm not sure if that's the exactly correct terminology, but a copy of the reference to the object will be passed in.

This means that any changes made to the object will be visible to you after the function is done executing.

Code:

var obj = {
  a: "hello"
};

function modify(o) {
  o.a += " world";
}

modify(obj);
console.log(obj.a); //prints "hello world"


Having said that, since it's only a copy of the reference that's passed in, if you re-assign the object inside of your function, this will not be visible outside of the function since it was only a copy of the reference you changed.

Code:

var obj = {
  a: "hello"
};

function modify(o) {
  o = {
    a: "hello world"
  };
}

modify(obj);
console.log(obj.a); //prints just "hello"

Solution 2 - Javascript

"Objects" are not values in JavaScript, and cannot be "passed".

All the values that you are dealing with are references (pointers to objects).

Passing or assigning a reference gives another reference that points to the same object. Of course you can modify the same object through that other reference.

Solution 3 - Javascript

This is more explanation for Pass by value and Pass by reference (Javascript). In this concept, they are talking about passing the variable by reference and passing the variable by reference.

Pass by value (Primitive Type)

var a = 3;
var b = a;
    
console.log(a); // a = 3
console.log(b); // b = 3

a=4;
console.log(a); // a = 4
console.log(b); // b = 3
  • applies to all primitive type in JS(string, number, boolean, undefined, null).
  • a is allocated a memory (say 0x001) and b creates a copy of the value in memory (say 0x002).
  • So changing the value of a variable doesn't affect the other, as they both resides in two different locations.

Pass by reference (objects)

var c = { "name" : "john" };    
var d = c;

console.log(c); // { "name" : "john" }
console.log(d); // { "name" : "john" }

c.name = "doe"; 

console.log(c); // { "name" : "doe" }    
console.log(d); // { "name" : "doe" }
  • JS engine assigns the object to the variable c, it points to some memory say (0x012)
  • when d=c, in this step d points to the same location (0x012).
  • changing the value of any changes value for both the variable.
  • functions are objects

Special case, Pass by reference (objects)

c = {"name" : "jane"}; 
console.log(c); // { "name" : "jane" }    
console.log(d); // { "name" : "doe" }
  • The equal(=) operator sets up new memory space or address

Solution 4 - Javascript

Basically, In JavaScript, there is no concept of Pass-By-Reference because Pass-by-value serves the purpose which makes JS so special. when we pass an object in JavaScript, 1)function needs to with the value and that value is the reference copy 2)This value to the address of the original object.

Solution 5 - Javascript

> How can I handle this problem? What if I want to change the object itself rather than its copy reference?

> I wanted to reassign an object within a function and its new value be visible in the calling function.

To add to the great accepted answer, and address unanswered questions in comments there, here's my take on passing by reference with a look at scope / closure in practice:

const obj = {
  count: 0,
}

function incrementReference(_obj) {
  obj.count++
}

function createIncrementByCopy(_obj) {
  let inner = {}
  Object.assign(inner, _obj)

  return function increment() {
    inner.count++
  }
}

function createScopedIncrement(_obj) {
  return function increment() {
    _obj.count++
  }
}
function createExtend(_obj) {
  return function increment(ext) {
    Object.assign(_obj, ext)
  }
}

console.log('obj', obj) // { count: 0 }

incrementReference(obj)
console.log('incrementReference ✅', obj.count) // 1

const incrementCopy = createIncrementByCopy(obj)
incrementCopy()
console.log('incrementCopy ❌', obj.count) // 1

const incrementA = createScopedIncrement(obj)
incrementA()
console.log('incrementA ✅', obj.count) // 2

const extendObj = createExtend(obj)
extendObj({ text: 'New Property!' })
console.log('extendObj ✅', obj) // { count: 2, text: 'New Property!' } 

The following article discusses a common confusion about the terminology, which I really can't speak to  https://dev.to/bytebodger/a-gotcha-of-javascript-s-pass-by-reference-1afm

Related (good context, more complex, different use case): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#copying_accessors

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBasitView Question on Stackoverflow
Solution 1 - JavascriptAdam RackisView Answer on Stackoverflow
Solution 2 - JavascriptnewacctView Answer on Stackoverflow
Solution 3 - JavascriptAshish Singh RawatView Answer on Stackoverflow
Solution 4 - JavascriptAadityaView Answer on Stackoverflow
Solution 5 - JavascriptptimView Answer on Stackoverflow