61

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'};    
}
5
  • 2
    Javascript automatically passes objects by reference all the time. Have you tried your above code to see if it already does what you want? Commented Jun 2, 2013 at 6:40
  • no, i haven't. i did read it. just wanted to confirm here. Commented Jun 2, 2013 at 6:41
  • 3
    JavaScript does not Pass By Reference. However, JavaScript does not make copies of objects when they are passed or assigned. As such, it is the same object with a different name - changes made to the object (from any name) affect said object. Commented Jun 2, 2013 at 6:43
  • 3
    It depends on what you mean by "pass by reference". In my view, "the same object with a different name" is the very definition of reference. Commented Jun 2, 2013 at 6:45
  • @jcsanyi This is why defining terms and avoiding ambiguity is important. (The Wikipedia article does admit that the term is ambiguous which is why I try to avoid using "Pass By Reference", except in cases where in unequivocally means that changing the local name binding affects the caller.) Commented Jun 2, 2013 at 6:47

5 Answers 5

175

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"

Sign up to request clarification or add additional context in comments.

13 Comments

en.wikipedia.org/wiki/Evaluation_strategy - I prefer "Call By [Object] Sharing" for it's directness, separation of implementation concerns, and reduced ambiguity with other call conventions. ECMAScript does not use "Reference" for this purpose in any part of the specification. (The Reference Specification Type does not apply to function calls.)
+1 for a clear description of what's different from a traditional pass-by-reference.
I think I made clear that a copy of the reference to the object is passed, and not the object itself.
How can I handle this problem? What if I want to change the object itself rather than its copy reference?
@Abhinav1602 I wanted to reassign an object within a function and it's new value be visible in the calling function.
|
7

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

Comments

6

"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.

3 Comments

Indeed - so a copy of the reference to the object is ..."passed" -_-
Indeed the object will not be passed, but a reference will, and you can modify its properties if you alter them inside of the receiver function
Simple, concise answer. When an object is assigned to a variable, the value assigned is a reference to the object. So all variables hold a value, but some values are references to objects (e.g. object, function, array) and some are literals (e.g. number, string, boolean and other primitives).
0

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.

Comments

0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.