Hello there, fellow JavaScript enthusiasts! Today, we're going to dive into the intriguing topic of pass by value vs pass by reference in JavaScript. This concept is crucial to understand because it affects how we work with variables and how they are passed to functions.
In JavaScript, primitive data types such as numbers, strings, booleans, null, and undefined are passed by value. This means that when you pass a primitive value to a function, a copy of that value is created and passed to the function. Let's illustrate this with an example:
function changeValue(num) {
num = 42;
console.log("Inside function:", num);
}
let myNumber = 10;
console.log("Before function call:", myNumber);
changeValue(myNumber);
console.log("After function call:", myNumber);
In this example, we have a function called changeValue
that takes a number as a parameter and assigns it a new value of 42. We then declare a variable myNumber
and assign it a value of 10.
When we call the changeValue
function and pass myNumber
as an argument, a copy of myNumber
is created and assigned to the num
parameter inside the function. Therefore, modifying the value of num
does not affect the original value of myNumber
. As a result, the output will be:
Before function call: 10
Inside function: 42
After function call: 10
On the other hand, objects (including arrays and functions) in JavaScript are passed by reference. This means that when you pass an object to a function, you are actually passing a reference to that object. Any modifications made to the object inside the function will affect the original object. Let's see an example:
function changeName(person) {
person.name = "John";
console.log("Inside function:", person);
}
let myPerson = { name: "Jane" };
console.log("Before function call:", myPerson);
changeName(myPerson);
console.log("After function call:", myPerson);
In this example, we have a function changeName
that takes an object person
as a parameter and modifies its name
property. We declare an object myPerson
with an initial name
of "Jane".
When we call the changeName
function and pass myPerson
as an argument, a reference to myPerson
is passed to the person
parameter inside the function. Thus, any changes made to person
will be reflected in the original myPerson
object. The output will be:
Before function call: { name: "Jane" }
Inside function: { name: "John" }
After function call: { name: "John" }
Understanding the difference between pass by value and pass by reference is crucial when working with JavaScript. It helps us predict how variables will behave when passed to functions and ensures we don't encounter unexpected side effects.
That's all for today's JavaScript journey! I hope this explanation with real-world examples has shed some light on the pass by value vs pass by reference concept. Happy coding, and until next time!
Follow me in X/Twitter, LinkedIn
Email : ashsajal@yahoo.com
Top comments (20)
As others have correctly said, JavaScript does not have 'pass by reference'. From MDN (emphasis mine):
Thank you, Jon, for your comment. Obviously, the docs are correct, but it says object arguments are passed by sharing. Here, "passed by sharing" isn't "pass by value" entirely. It's quite similar to "pass by reference". Actually it is an evaluation strategy that is intermediate between call by value and call by reference.
Sell Wikipedia about pass by sharing
Even the example provided after the explanation is isn't satisfying "pass by value".
Objects are a reference type (as are arrays and functions). This doesn't mean however that they are passed by reference to a function (if they were, it would be a reference to a reference type). You're confusing two different things.
If JS used pass by reference, you would be able to reassign arguments (i.e. assign an entirely new value or object to them - which would then be seen outside the function). This simply is not possible in JS
Jon, I appreciate your perspective and the documentation you've shared. It has helped clarify my doubt, and I hope it benefits others too.
JavaScript doesn't have pass-by-reference. All arguments are passed by value. Values being mutable (objects) or immutable (primitives) has nothing to do with this.
JavaScript does not have traditional pass-by-reference like other languages. However, when dealing with objects (reference types), a reference to the object is passed to the function, allowing changes to the object within the function to affect the original object. This is because JavaScript does not create a copy of the object, but rather passes a reference to the object. This is why changes made to the object inside the function can affect the original object.
Try the code below
I think the confusion here is in the fact that objects are reference types, when they are made, they are allocated somewhere else in memory and a pointer to that location is stored in a variable.
All arguments are passed by value, so the pointer is copied and sent to the function. It's a copy of the pointer, not a copy of the reference to which the pointer refers. Dereferencing the copied pointer just results in finding the same object as the pointer is an exact copy.
In this code we are allocating variables on a stack frame. The stack can contain primitives and primitives include pointers, they don't include objects. A 5 is put on the stack for
f
and, somewhere else in memory, an object is created{f:5}
, the pointer to this object is put ino
. Copyingo
occurs when we callotherStuff
but that is just the pointer, not the object.In JavaScript we don't have structured value types -> no structs -> no copy by value structured data, we only have objects that are allocated on the heap for structured data, these are always reference types.
JavaScript does not have call by reference.
JavaScript does not contain pointers, which are the "reference" in pass by reference, but for objects it has the same impact as pass-by-reference... non-primitive values can be mutated.
Apparently this is called pass-by-sharing, though it is not something that I would think to call it.
I think of it as abstracted pass-by-reference. A variable or property which is not a primitive ultimately does have a pointer at a lower level than the language provides. Accessing or mutating the object is accomplished through that hidden reference; we just don't get to see it. If you reassign the parameter, you replace the reference, so the original object from outside the scope is inaccessible.
This essentially follows the description of pass-by-sharing...certain there are certain types that use a reference to share an object.
There's been lots of attempts at coming up with new words for the combination of call-by-value and reference types, but at the end of the day, those are still, strictly speaking, call-by-value. The value being a reference to some other data that may or may not be mutable.
It's also only half true that JavaScript doesn't have pointers. Pointers are a low-level construct that represents a reference to some data via its memory location as a number, so you can do some degree of arithmetic on them. JavaScript abstracts these internals away, but still gives us references to objects that, internally, use pointers. We can't do arithmetic on these references, but they still can do other things pointers can do, like being passed into a function to be mutated.
As for primitives, since they are all immutable in JavaScript, there isn't really a meaningful distinction between how they are shared. Internally, the VM probably shares at least strings by reference, and might do the same for larger numbers.
If we think of, say, the integer
20
as an instance of some immutable number class, where all operations on it create a new instance, and calling a function with it passes a reference to said number as an argument, then we can still expect it to behave the exact same way as if we think of it as a plain integer that gets copied into whatever memory the function uses.This is why I think concepts like "pass-by-sharing" are somewhat missing the point: They tell us only about the values we're dealing with and their types, whereas the actual "call-by-reference" / "call-by-value" distinction tells us something about the variables holding the values.
In call-by-reference, the function isn't called on the value itself, but on the variable. If we assign a new primitive value to the function argument, the actual variable outside of it will be changed accordingly. Internally this will likely be implemented by some sort of reference type, but if a subroutine is inlined, then it may well not be. Either way, that's an implementation detail that shouldn't be paid much attention when talking about conceptual language features.
This article is totally wrong. JavaScript is pass by value only.
On the other hand, C++ has both pass by value & pass by reference:
JavaScript does not have true pass by reference like some other languages. In JavaScript, objects are passed by reference, while primitives are passed by value. This means that when you pass an object to a function, you're passing a reference to that object, but when you pass a primitive (like a number or a string), you're passing a copy of its value.
You can try the code below that I included in the article before.
Sorry, but you are confusing people. It is really important to understand exactly, how Javascript objects work.
Did you kill 'Jane' or not??? You should know!
Objects are references, if you use them as a parameter, you just pass a copy of that reference. In fact, it is not easy to make a deep copy in JS. If objects would be passed "by reference", this schould work (which does not).
Thank you, Eckehard, for your input. Would you mind elaborating further?
Look here for details.
Did the article clarify the doubt about, pass by value vs pass by referrence?
On the surface, you can say that primitives are "passed by value", and objects are "passed by reference". Actually, JavaScript only passes by value, as Java does.
Probably the actual implementation explains how: JavaScript passes the reference to the object to functions (by value). When the value is a primitive, however, the value is stored in the reference itself. This explains the behaviour which can be, at first, strange.
Thanks for you comment Perez. In JavaScript, everything is passed by value, but for objects, it's the reference to the object that's passed. Primitives get their values copied directly, while objects get their references copied. This can lead to some surprises if not handled carefully.
How can i do pass by reference for primitive data types??
It's not possible. But you can wrap the primitive data in an object which is unnecessary I guess. Thanks for your comment.