By Danail Nachev

2009-02-05 21:23:56 8 Comments

The primitive types (number, string, etc.) are passed by value, but objects are unknown, because they can be both passed-by-value (in case we consider that a variable holding an object is in fact a reference to the object) and passed-by-reference (when we consider that the variable to the object holds the object itself).

Although it doesn't really matter at the end, I want to know what is the correct way to present the arguments passing conventions. Is there an excerpt from JavaScript specification, which defines what should be the semantics regarding this?


@Asad Raza 2020-04-29 22:17:09

Mostly simplest way

// Copy JS object without reference
var first = {"a":"value1","b":"value2"};
var clone = JSON.parse( JSON.stringify( first ) ); 

var second = ["a","b","c"];
var clone = JSON.parse( JSON.stringify( second ) ); 

@D. Pardal 2020-05-28 08:50:22

JSON.parse( JSON.stringify( obj ) ) is a horrible way to deep-clone objects. Not only it's not only slow, but it can also cause data loss.

@Quentin 2020-07-13 08:52:55

This doesn't appear to address the question that was asked at all

@deworde 2010-09-03 17:17:22

It's interesting in JavaScript. Consider this example:

function changeStuff(a, b, c)
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);


This produces the output:

  • If obj1 was not a reference at all, then changing obj1.item would have no effect on the obj1 outside of the function.
  • If the argument was a proper reference, then everything would have changed. num would be 100, and obj2.item would read "changed".

Instead, the situation is that the item passed in is passed by value. But the item that is passed by value is itself a reference. Technically, this is called call-by-sharing.

In practical terms, this means that if you change the parameter itself (as with num and obj2), that won't affect the item that was fed into the parameter. But if you change the INTERNALS of the parameter, that will propagate back up (as with obj1).

@Peter Lee 2011-12-24 00:15:20

This is exactly same (or at least semantically) as C#. Object has two type: Value (primitive types) and Reference.

@Jpnh 2012-01-04 13:41:20

I think this is also used in Java: reference-by-value.

@jinglesthula 2012-01-30 19:26:15

the real reason is that within changeStuff, num, obj1, and obj2 are references. When you change the item property of the object referenced by obj1, you are changing the value of the item property that was originally set to "unchanged". When you assign obj2 a value of {item: "changed"} you are changing the reference to a new object (which immediately goes out of scope when the function exits). It becomes more apparent what's happening if you name the function params things like numf, obj1f, and obj2f. Then you see that the params were hiding the external var names.

@ruffin 2012-04-16 19:09:30

I'm dumb enough to need to know if using let over var in this example makes any practical difference.

@deworde 2012-04-16 19:38:05

Don't think so, as far as I've ever been able to tell, the only difference is that let gives you C/C++ "loop-level" scoping, whereas var only gives you function-level scoping. I think there's some quirky special features, but have avoided them for long enough not to care.

@will824 2012-05-02 17:22:03

Its just me or someone else feels Javascript is quite "strange" on the Reference passing...?

@jedd.ahyoung 2013-06-19 00:25:54

Upvoted. I tripped over this, thinking that the "pass by reference" thing was true pass by reference - I thought that updating the reference would overwrite the original update (updating all the references). Now I see. Now, I think I can actually fix my code!

@BartoNaz 2013-07-31 21:32:46

Thanks for nice explanation. Is there any way to make the obj2 be replaced by a new one from inside the changeStuff function?

@Tim Goodman 2013-08-05 15:26:29

@BartoNaz Not really. What you want is to pass the reference by reference, instead of passing the reference by value. But JavaScript always passes the reference by value, just like it passes everything else by value. (For comparison, C# has pass-reference-by-value behavior similar to JavaScript and Java, but lets you specify pass-reference-by-reference with the ref keyword.) Usually you would just have the function return the new object, and do the assignment at the point where you call the function. E.g., foo = GetNewFoo(); instead of GetNewFoo(foo);

@Tim Goodman 2013-08-05 15:35:37

I suppose you could also work around this by assigning the object to a property of some wrapper object. Then you pass in the wrapper object, and update its property to point to the new object. (Of course, any other variables that hold references to the old object would still hold a reference to the old object.) But, generally I would recommend just returning the new object instead -- it communicates your intent more clearly, and keeps your function free of side-effects.

@BartoNaz 2013-08-05 15:40:59

Thank you, Tim. That is the way I made it work. Just returning the modified object...

@Matt Greer 2014-01-14 16:58:19

argh! JavaScript is a pure pass by value language. It's just that the values being passed around are references when not dealing with primitives.

@deworde 2014-01-14 17:47:47

@MattGreer "Instead, the situation is that the item passed in is passed by value. But the item that is passed by value is itself a reference" I think we're in agreement here.

@chiccodoro 2014-05-02 09:19:40

Although this answer is the most popular it can be slightly confusing because it states "If it was pure pass by value". JavaScript is pure pass-by-value. But the value that is passed is a reference. This is not constrained to parameter-passing at all. You could simply copy the variable by var obj1 = { item: 'unchanged' }; var obj2 = obj1; obj2.item = 'changed'; and would observe the same effect as in your example. Therefore I personally refer the answer of Tim Goodman

@Chris Cirefice 2014-05-27 16:52:09

Very interesting... I looked through the answers and comments, but no ECMA link. Can anyone provide a resource to the standard where this behavior is defined? I'm not so great at finding this kind of stuff myself. I think it would be very helpful to have as a reference in this answer :)

@Anthony Scaife 2014-06-27 15:24:30

For PHP programmers - This example would work the same in PHP.

@deworde 2015-04-15 07:16:46

@chiccodoro Saying "it's pure pass-by-value, except that you're passing a reference by value" is confusing at the level of anyone who would actually ask this question. In "observed behaviour" terms, I'd want "pure" pass-by-value (in as much as that term has any meaning) to be deep copy,. Obviously it's implemented as "pure pass-by-value" at the "implementing a JavaScript engine" level, but if you're working at that level you're not asking this question (hopefully possibly please)

@chiccodoro 2015-04-15 09:11:50

@deworde - I understand your point. In my opinion though, "pass-by-reference" means that you can change the value of the parameter. You can do this in languages like VB and C# (by using the ref modifier). This way you can do things like var a = 2; CallAFunction(ref a); and after that, a is not 2 anymore. Likewise, a reference can be changed: var a = new A(); CallAnotherFunction(ref a) and after that, a does no longer point to the newly built object. Neither of those things can happen in JavaScript - hence I claim it is pure pass-by-value.

@jgmjgm 2015-07-01 00:04:41

In high level languages scalars are nearly always pass by value or copies (often COW underneath). This is well known. Objects are always passed by reference automatically. Cloning an object is not that easy. Basic non-scalar types like maps and arrays can vary. If they are passed by value there will often be syntax to explicitly pass by reference. Finally, where there is no explicit support for some types to be passed by reference, they can be boxed/wrapped. Passing scalar types by reference is rarely beneficial if the scripting language can use COW so sometimes it is not supported.

@Pointy 2015-11-27 23:50:51

@jgmjgm that's not what pass-by-reference means. I acknowledge that it's confusing, but the terminology was coined before programming languages had things like objects. Pass-by-reference means that the called environment can alter the value of a variable in the calling environment. Note that I wrote "the value of a variable" - I don't mean the value of an object, but a variable, like a symbol declared with var in JavaScript. Because that's not possible, JavaScript does not have pass by reference. (C++ does, sort-of, via & parameters.)

@Matthew Oakley 2016-08-02 02:35:21

See Tim Goodman's answer below. It is correct. Always pass-by-value.

@jgmjgm 2017-02-16 13:18:57

@Pointy You might be in that respect and for the phrase in terms of canon. Versus implementations, the treatment in plain English it is more of a head scratcher. The definition you is including the purpose (altering) but reference is reference irrespective of ultimate purpose. It could also be about performance or the read side where something down another branch is altering it. Colloquially it in such contexts it tends to merely mean in effect passing a pointer. The term reference would abstract the exact pointer mechanism. Performance is the main place where there's a conflict in meaning.

@Orafu 2017-08-19 05:10:57

I found this helpful, as it explains what is copied when passing arguments to a function. Important for strings, as a copy of the reference to the string is passed. (But as javascript strings are immutable, the string is not "shared", only memory is saved.) Note that "passed by reference" in the article is not call by reference: a copy of the ref to an object is passed, not a ref to a variable in the caller.

@Eureka 2017-09-21 19:26:41

Regardless of how people want to describe the thing being passed, the EXAMPLE in this answer is brilliantly clear: it lets readers immediately recognise the presence of some subtlety, and tells them how the 3 common situations are handled. I keep coming back to this whenever I am in doubt.

@Scott Marcus 2018-04-05 17:23:50

This is not how C# (.NET) works. In .NET, yes, you have value and reference types, but in .NET, you can control whether you want either of them passed by value or by reference, which you can't do in JavaScript because everything is only ever passed by value. Passing by reference doesn't exist in JavaScript. See this.

@phant0m 2019-06-16 12:41:20

@chiccodoro I have taken the liberty to remove the wording "pure pass-by-value" and hijack this post since it's so popular to explain in more accurately.

@deworde 2019-06-18 16:24:14

@phant0m While I found the details your answer really interesting, I think it lost the clarity that made this answer helpful (at 10897 characters, your change was effectively a blogpost) In some ways, I think it would make more sense as a separate answer. The discussion around "'pure' pass-by-value" was over a year ago, and I didn't see any need to update it, as the description after the term is pretty clear. If it really bugs you, a simpler change to "if the argument was not a reference at all" would be probably be more suitable.

@Wayneio 2019-12-15 19:54:50

This may be an old question but I think it's genuinely the best answer on the internet to how pass-by-value(when value is a ref) on the internet

@deworde 2019-12-18 16:22:32

@Wayneio Thank you! That more than makes up for the fact I've unnecessarily avoided thousands of points of rep by making it community wiki.

@deworde 2020-04-25 16:27:07

@BenAston I found your answer really interesting, but feel it lacks some of the straightforwardness of the original that people have suggested they found helpful. If you'd like to submit your own answer to this question, I'll upvote it.

@Ben Aston 2020-04-25 19:24:49

Fair enough. But JavaScript is pass by value. That’s it. Full stop. I think your answer needs to state that upfront. Also: JavaScript behaves the same as the default behaviour of Java, C# and PHP, so calling it “interesting” suggests a novelty that isn’t there. For future readers, we are referring to revision 19 here.

@deworde 2020-04-25 21:21:14

Yeah, we go round that argument about once a year. I came to my conclusion over it in 2015, and haven't shifted since.…

@Ben Aston 2020-04-26 07:00:21

This is not a personal conclusion thing. It is a straightforward fact. JavaScript is pass by value. That’s it. Everything stems from this fact. And JavaScript’s behaviour is not “interesting”. It matches exactly, the default behaviour of Java (and C# and PHP), and is similar to Python.

@deworde 2020-04-26 13:50:22

The phrasing is a personal conclusion. Your phrasing matches the textbook that clearly didn't help the people who come to this question, or they wouldn't have searched for it. JavaScript may be pass by value in its parameters (as the answer states) but because JS handles all non-simple types as references, focusing on it simply being pass by value fails to explain the pretty fundamental behaviour shown above. And matching exactly the behaviour of those languages does not make it not "interesting". The effect on parameter manipulation is interesting in and of itself.

@Mohammed Zameer 2017-08-10 12:43:08

sharing what I know of references in JavaScript

In JavaScript, when assigning an object to a variable, the value assigned to the variable is a reference to the object:

var a = {
  a: 1,
  b: 2,
  c: 3
var b = a;

// b.c is referencing to a.c value
console.log(b.c) // Output: 3
// Changing value of b.c
b.c = 4
// Also changes the value of a.c
console.log(a.c) // Output: 4

@Quentin 2017-08-10 12:48:53

This is an overly simplistic answer which says nothing that earlier answers haven't explained better. I'm confused about why you call out arrays as a special case.

@RobG 2019-07-27 11:29:49

"objects are stored as references" is misleading. What I think you mean is that when assigning an object to a variable, the value assigned to the variable is a reference to the object.

@amaster 2020-04-11 04:28:53

this does not address the problem of updating an object inside of a function that does not update the object outside of the function. That is the whole picture where it seems to work as values instead of reference. Hence -1

@Mohammed Zameer 2020-04-11 14:40:14

@amaster Thanks for pointing that out! Can you suggest an edit, please?

@amaster 2020-04-13 00:08:41

Haha, I tried... my suggested edit changed too much amd was not allowed

@Mohammed Zameer 2020-04-14 14:30:21

@amaster I cannot trace your suggestion man!

@amaster 2020-04-14 15:13:31

@xameeramir it is because It did not get submitted. My suggestion changed too much of your answer so it was blocked by SO. There are other good answers here. I may add an answer at a later date to express my point concisely

@ashkan nasirzadeh 2019-11-14 00:48:46

well, it's about 'performance' and 'speed' and in the simple word 'memory management' in a programming language.

in javascript we can put values in two layer: type1-objects and type2-all other types of value such as string & boolean & etc

if you imagine memory as below squares which in every one of them just one type2-value can be saved:

enter image description here

every type2-value (green) is a single square while a type1-value (blue) is a group of them:

enter image description here

the point is that if you want to indicate a type2-value, the address is plain but if you want to do the same thing for type1-value that's not easy at all! :

enter image description here

and in a more complicated story:

enter image description here

so here references can rescue us: enter image description here

while the green arrow here is a typical variable, the purple one is an object variable, so because the green arrow(typical variable) has just one task (and that is indicating a typical value) we don't need to separate it's value from it so we move the green arrow with the value of that wherever it goes and in all assignments, functions and so on ...

but we cant do the same thing with the purple arrow, we may want to move 'john' cell here or many other things..., so the purple arrow will stick to its place and just typical arrows that were assigned to it will move ...

a very confusing situation is where you can't realize how your referenced variable changes, let's take a look at a very good example:

let arr = [1, 2, 3, 4, 5]; //arr is an object now and a purple arrow is indicating it
let obj2 = arr; // now, obj2 is another purple arrow that is indicating the value of arr obj
let obj3 = ['a', 'b', 'c'];
obj2.push(6); // first pic below - making a new hand for the blue circle to point the 6
//obj2 = [1, 2, 3, 4, 5, 6]
//arr = [1, 2, 3, 4, 5, 6]
//we changed the blue circle object value (type1-value) and due to arr and obj2 are indicating that so both of them changed
obj2 = obj3; //next pic below - changing the direction of obj2 array from blue circle to orange circle so obj2 is no more [1,2,3,4,5,6] and it's no more about changing anything in it but we completely changed its direction and now obj2 is pointing to obj3
//obj2 = ['a', 'b', 'c'];
//obj3 = ['a', 'b', 'c'];

enter image description here enter image description here

@igor 2011-05-12 22:20:25

A very detailed explanation about copying, passing and comparing by value and by reference is in this chapter of the "JavaScript: The Definitive Guide" book.

Before we leave the topic of manipulating objects and arrays by reference, we need to clear up a point of nomenclature.

The phrase "pass by reference" can have several meanings. To some readers, the phrase refers to a function invocation technique that allows a function to assign new values to its arguments and to have those modified values visible outside the function. This is not the way the term is used in this book.

Here, we mean simply that a reference to an object or array -- not the object itself -- is passed to a function. A function can use the reference to modify properties of the object or elements of the array. But if the function overwrites the reference with a reference to a new object or array, that modification is not visible outside of the function.

Readers familiar with the other meaning of this term may prefer to say that objects and arrays are passed by value, but the value that is passed is actually a reference rather than the object itself.

@Jörg W Mittag 2020-06-01 11:17:13

Wow, this is incredibly confusing. Who in their right mind would define a well-established term to mean the exact opposite and then use it that way? No wonder so many answers here on this question are so confused.

@Ashish Singh Rawat 2018-09-25 17:31:53

This is little 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

console.log(a); // a = 4
console.log(b); // b = 3
  • applies to all primitive type in JavaScript (string, number, Boolean, undefined, and 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 reside 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" } = "doe";

console.log(c); // { "name" : "doe" }
console.log(d); // { "name" : "doe" }
  • The JavaScript engine assigns the object to the variable c, and 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

@georgeawg 2019-03-27 16:04:36

In your so-called special case, it is not the assignment operator that causes the allocation of memory space, it is the object literal itself. The curley bracket notation causes the creation of a new object. The property c is set to a copy of the new object's reference.

@Ray Perea 2014-08-04 11:06:56

My two cents... This is the way I understand it. (Feel free to correct me if I'm wrong)

It's time to throw out everything you know about pass by value / reference.

Because in JavaScript, it doesn't matter whether it's passed by value or by reference or whatever. What matters is mutation vs assignment of the parameters passed into a function.

OK, let me do my best to explain what I mean. Let's say you have a few objects.

var object1 = {};
var object2 = {};

What we have done is "assignment"... We've assigned 2 separate empty objects to the variables "object1" and "object2".

Now, let's say that we like object1 better... So, we "assign" a new variable.

var favoriteObject = object1;

Next, for whatever reason, we decide that we like object 2 better. So, we simply do a little re-assignment.

favoriteObject = object2;

Nothing happened to object1 or to object2. We haven't changed any data at all. All we did was re-assign what our favorite object is. It is important to know that object2 and favoriteObject are both assigned to the same object. We can change that object via either of those variables. = 'Fred';
console.log( // Logs Fred = 'Joe';
console.log(; // Logs Joe

OK, now let's look at primitives like strings for example

var string1 = 'Hello world';
var string2 = 'Goodbye world';

Again, we pick a favorite.

var favoriteString = string1;

Both our favoriteString and string1 variables are assigned to 'Hello world'. Now, what if we want to change our favoriteString??? What will happen???

favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'

Uh oh.... What has happened. We couldn't change string1 by changing favoriteString... Why?? Because we didn't change our string object. All we did was "RE ASSIGN" the favoriteString variable to a new string. This essentially disconnected it from string1. In the previous example, when we renamed our object, we didn't assign anything. (Well, not to the variable itself, ... we did, however, assign the name property to a new string.) Instead, we simply mutated the object which keeps the connections between the 2 variables and the underlying objects. (Even if we had wanted to modify or mutate the string object itself, we couldn't have, because strings are actually immutable in JavaScript.)

Now, on to functions and passing parameters.... When you call a function, and pass a parameter, what you are essentially doing is an "assignment" to a new variable, and it works exactly the same as if you simply assigned using the equal (=) sign.

Take these examples.

var myString = 'hello';

// Assign to a new variable (just like when you pass to a function)
var param1 = myString;
param1 = 'world'; // Re assignment

console.log(myString); // Logs 'hello'
console.log(param1);   // Logs 'world'

Now, the same thing, but with a function

function myFunc(param1) {
    param1 = 'world';

    console.log(param1);   // Logs 'world'

var myString = 'hello';
// Calls myFunc and assigns param1 to myString just like param1 = myString

console.log(myString); // logs 'hello'

OK, now let’s give a few examples using objects instead... first, without the function.

var myObject = {
    firstName: 'Joe',
    lastName: 'Smith'

// Assign to a new variable (just like when you pass to a function)
var otherObj = myObject;

// Let's mutate our object
otherObj.firstName = 'Sue'; // I guess Joe decided to be a girl

console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Sue'

// Now, let's reassign the variable
otherObj = {
    firstName: 'Jack',
    lastName: 'Frost'

// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object has no influence on the other
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Jack';

Now, the same thing, but with a function call

function myFunc(otherObj) {

    // Let's mutate our object
    otherObj.firstName = 'Sue';
    console.log(otherObj.firstName); // Logs 'Sue'

    // Now let's re-assign
    otherObj = {
        firstName: 'Jack',
        lastName: 'Frost'
    console.log(otherObj.firstName); // Logs 'Jack'

    // Again, otherObj and myObject are assigned to 2 very different objects
    // And mutating one object doesn't magically mutate the other

var myObject = {
    firstName: 'Joe',
    lastName: 'Smith'

// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject

console.log(myObject.firstName); // Logs 'Sue', just like before

OK, if you read through this entire post, perhaps you now have a better understanding of how function calls work in JavaScript. It doesn't matter whether something is passed by reference or by value... What matters is assignment vs mutation.

Every time you pass a variable to a function, you are "Assigning" to whatever the name of the parameter variable is, just like if you used the equal (=) sign.

Always remember that the equals sign (=) means assignment. Always remember that passing a parameter to a function in JavaScript also means assignment. They are the same and the 2 variables are connected in exactly the same way (which is to say they aren't, unless you count that they are assigned to the same object).

The only time that "modifying a variable" affects a different variable is when the underlying object is mutated (in which case you haven't modified the variable, but the object itself.

There is no point in making a distinction between objects and primitives, because it works the same exact way as if you didn't have a function and just used the equal sign to assign to a new variable.

The only gotcha is when the name of the variable you pass into the function is the same as the name of the function parameter. When this happens, you have to treat the parameter inside the function as if it was a whole new variable private to the function (because it is)

function myFunc(myString) {
    // myString is private and does not affect the outer variable
    myString = 'hello';

var myString = 'test';
myString = myString; // Does nothing, myString is still 'test';

console.log(myString); // Logs 'test'

@technosaurus 2015-03-26 09:49:53

For any C programmers, think of char*. foo(char *a){a="hello";} does nothing, but if you do foo(char *a){a[0]='h';a[1]='i';a[2]=0;} it is changed outside because a is a memory location passed by value that references a string (char array). Passing structs (similar to js objects) by value in C is allowed, but not recommended. JavaScript simply enforces these best practices and hides the unnecessary and usually undesired cruft... and it sure makes for easier reading.

@Pointy 2015-11-27 23:52:45

This is correct - the terms pass-by-value and pass-by-reference have meanings in programming language design, and those meanings have nothing at all to do with object mutation. It's all about how function parameters work.

@Machtyn 2016-02-22 20:23:24

Now that I understand that obj1 = obj2 means that both obj1 and obj2 are now pointing to the same reference location, and if I modify the internals of obj2, referencing obj1 will expose the same internals. How do I copy an object such that when I do source = { "id":"1"}; copy = source /*this is wrong*/;"2" that source is still {"id":"1"}?

@C Perkins 2017-05-30 19:36:40

I posted another answer with traditional definitions to hopefully reduce confusion. Traditional definitions of "pass-by-value" and "pass-by-reference" were defined back in the day of memory pointers before automatic dereferencing. It was perfectly well understood that an object variable's value was actually the memory pointer location, not the object. Although your discussion of assignment vs mutation is perhaps useful, it is not necessary to throw out the traditional terms nor their definitions. Mutation, assignment, pass-by-value, pass-by-reference, etc. must not contradict each other.

@ebram khalil 2017-06-16 11:24:50

does "Number" is a "immutable" too?

@Scott Marcus 2018-04-05 17:28:18

This may be interesting to read, but much more complicated than necessary and a bit off the actual point. It's actually pretty simple if you understand that there is a difference between having a value or reference type and passing that type. Everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

@phant0m 2019-06-16 09:44:20

I have tried clearing up some of the wording like "no longer mutates the other object" (there was no "other" object) to try to reduce the confusion. I have left in the comments about "pass-by-reference vs pass-by-value" being irrelevant because I didn't want to completely change your post in an edit. It does make a difference. I think your focus on setting the debate over terminology aside for a moment and talking about regular assignments first (where no one ever discusses how one programming language behaves vs another) is great!

@phant0m 2019-06-16 09:46:03

However, pass-by-reference would absolutely change what happens. Your entire explanation drives home the fact that in JavaScript, function parameters are separate variables and assigning to different variables has no influence on the other. Yes! But: With pass-by-reference, those parameters would not be separate, they would essentially be an alias for the caller's variable. So assignment to a parameter variable is actually an assignment to the caller's variable, not to a separate independent variable.

@phant0m 2019-06-16 09:56:13

@ScottMarcus The thing that bugs me about the post is that it says it doesn't matter whether it's p-b-r or p-b-v. Otherwise, I think talking about assignments in length is a great idea. People (that don't make the distinction between value/ref types) always jump on this topic in the context of argument passing. The fact that it behaves the exact same way and no one ever thought of claiming "assignment to variables works differently in Java than in Python/JavaScript/Ruby" is frankly a bit astonishing, but they claim that parameter passing is different, even though it, too, works the same way.

@Olivera Kovacevic 2013-04-27 12:36:40

Simple values inside functions will not change those values outside of the function (they are passed by value), whereas complex ones will (they are passed by reference).

function willNotChange(x) {

    x = 1;

var x = 1000;


document.write('After function call, x = ' + x + '<br>'); // Still 1000

function willChange(y) {

    y.num = 2;

var y = {num: 2000};

document.write('After function call y.num = ' + y.num + '<br>'); // Now 2, not 2000

@Parijat Kalia 2015-11-10 19:02:42

that is ridiculous, y will change because of functional level scoping, it gets hoisted not because it is passed by reference.

@Scott Marcus 2018-04-05 17:25:58

No, everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

@uriz 2013-02-25 12:33:32

  1. Primitives (number, Boolean, etc.) are passed by value.
    • Strings are immutable, so it doesn't really matter for them.
  2. Objects are passed by reference (the reference is passed by value).

@Scott Marcus 2018-04-05 17:25:29

No, everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

@Jörg W Mittag 2020-06-01 10:48:28

Your second statement is contradicting itself.

@user779764 2011-06-02 23:04:31

An object outside a function is passed into a function by giving a reference to the outside object.

When you use that reference to manipulate its object, the object outside is thus affected. However, if inside the function you decided to point the reference to something else, you did not affect the object outside at all, because all you did was re-direct the reference to something else.

@Dooley 2009-08-21 15:30:52

Primitives are passed by value and objects are passed by reference. This is quite different from other languages like C, Visual Basic, or Delphi. I can't say how they handle objects and primitives exactly, but I know of Visual Basic and Delphi that it can (and should) be specified.

PHP does something similar since version 5: all objects are passed by reference, but all primitives may be passed by reference, if preceded by an ampersand (&). Otherwise primitives are passed by value.

So in JavaScript, if I pass an object X into a function via a parameter, it will still be X. If you are changing data inside the function (or any other object, but that's not important) that new value is also available outside the function.

@Tom 2011-08-29 11:13:55

"that new value is also available outside the function" This is false. See The value is not changed, instead the reference is changed.

@Olgun Kaya 2017-09-06 09:01:17

@Tom, changing your code to var x = {hi : 'hi'}; change(x); console.log(x.hi); function change(x) { x.hi = 'changed'; } changes the behavior.

@Scott Marcus 2018-04-05 17:21:43

@Ross 2009-02-05 22:02:47

An easy way to determine whether something is "pass by reference" is whether you can write a "swap" function. For example, in C, you can do:

void swap(int *i, int *j)
    int t;
    t = *i;
    *i = *j;
    *j = t;

If you can't do the equivalent of that in JavaScript, it is not "pass by reference".

@Matt Greer 2010-04-26 19:35:57

This isn't really pass by reference. You are passing pointers into the function, and those pointers are being passed in by value. A better example would be C++'s & operator or C#'s "ref" keyword, both are truly pass by reference.

@Scott Marcus 2018-04-05 17:21:14

Even easier is that everything is passed by value in JavaScript.

@Scott Marcus 2018-04-05 17:21:46

@Michael Roberts 2009-02-05 21:49:37

JavaScript is always pass-by-value; everything is of value type.

Objects are values, and member functions of objects are values themselves (remember that functions are first-class objects in JavaScript). Also, regarding the concept that everything in JavaScript is an object; this is wrong. Strings, symbols, numbers, booleans, nulls, and undefineds are primitives.

On occasion they can leverage some member functions and properties inherited from their base prototypes, but this is only for convenience. It does not mean that they are objects themselves. Try the following for reference:

x = "test";
alert(; = 12;

In both alerts you will find the value to be undefined.

@geowa4 2009-02-05 22:10:03

Pass 5 into the function then call theParam.toPrecision(4), and it works. This means that it is an object. If it is able to use anything from its prototype, then it must be an object. It's not like Ruby in that you can do 5.someMethod(), but every variable is wrapped in an appropriate object.

@geowa4 2009-02-05 22:13:36

It's not an object to start, but when a method is called on it, it gets wrapped.

@Michael Roberts 2009-02-05 22:27:21

The wrapper is discarded once the invocation is complete however, it is purely a convention and does not actually replace the original string with an object.

@KooiInc 2009-02-06 06:49:03

I don't know Ruby, but in js you can do (5).someMethod()

@Nick 2010-10-13 21:43:26

-1, it is not always pass by value. From MDC: "If you pass an object (i.e. a non-primitive value, such as Array or a user-defined object) as a parameter, a reference to the object is passed to the function."

@cHao 2012-05-10 14:21:34

@Nick: It is always pass by value. Period. A reference to the object is passed by value to the function. That's not passing by reference. "Pass by reference" could almost be thought of as passing the variable itself, rather than its value; any changes the function makes to the argument (including replacing it with a different object entirely!) would be reflected in the caller. That last bit isn't possible in JS, because JS does not pass by reference -- it passes references by value. The distinction is subtle, but rather important to understanding its limitations.

@slacktracer 2012-08-16 01:49:45

For future stackers... About this reference of yours: x = "teste"; = 12; etc. Just because a property isn't persistent it doesn't mean it's not an object. As MDN says: In JavaScript, almost everything is an object. All primitive types except null and undefined are treated as objects. They can be assigned properties (assigned properties of some types are not persistent), and they have all characteristics of objects. link

@Garrett 2013-12-14 18:05:58

Michael Roberts is correct on both counts. As usual, the misconceptions seem to float to the top.

@Garrett 2013-12-14 18:16:38

MDN is a user-edited wiki and it is wrong there. The normative reference is ECMA-262. See S. 8 "The Reference Specification Type", which explains how references are resolved, and also 8.12.5 "[[Put]]", which is used to explain AssignmentExpression to a Reference, and, for object coersion 9.9 ToObject. For primitive values, Michael already explained what ToObject does, as in the specification. But see also s. 4.3.2 primitive value.

@WonderLand 2016-05-05 05:56:57

@cHao for array passed as parameters @Nick is right: if you modify the array in the destination function, also the original one is modified. ( this sounds to me as it is passed as reference. ) That imho is what ppl want to know when they ask about reference/value stuff...

@cHao 2016-05-05 17:49:10

@WonderLand: No, he's not. People who've never been able to pass by reference may never understand the differences between passing by reference and passing a reference by value. But they're there, and they matter. I don't care to misinform people just cause it sounds easier.

@WonderLand 2016-05-06 06:32:18

@cHao if I pass an array in a function and I modify that array in my function then the original array is also changes. you said a reference to the object is passed, that does't mean the value itself is passed but something similar to a pointer ...

@cHao 2016-05-06 13:32:20

@WonderLand: It means that arrays are not values in JS. References to arrays are values. And when you "pass an array", you are copying and passing that value, not the array itself. You might be blind to the difference, but that difference makes certain things impossible in JS that are possible in languages that allow for passing by reference.

@LiweiZ 2016-07-27 04:41:06

For those of you feel confused like me,…, the second most upvoted answer explains in detail.

@Narayon 2016-10-19 15:22:12

In JS, primitives are not objects, but because JS is a dynamic language(don't have types) when you try to use methods on a primitive JS converts it to an object(p.e. an int is converted to Number) while using the method. That said, those primitive objects are immutable, that's why you can't add any extra methods to it. I added an answer that tries to explain passing by reference using a low level language example. I think it's easier to understand.

@Scott Marcus 2018-04-05 17:05:54

No, not everything is a value. There are primitives, which are value types and Objects, which are reference types. But, in either case, when passed they are all passed by value.

@Scott Marcus 2019-04-11 15:42:37

@Narayon because JS is a dynamic language(don't have types) JavaScript isn't a "dynamic" language - it's an interpreted (compiled on demand) language, but that doesn't mean it doesn't have types. It sure does. It has primitive types and Object types.

@Shog9 2009-02-05 21:37:34

The variable doesn't "hold" the object; it holds a reference. You can assign that reference to another variable, and now both reference the same object. It's always pass by value (even when that value is a reference...).

There's no way to alter the value held by a variable passed as a parameter, which would be possible if JavaScript supported passing by reference.

@user3186555 2017-10-02 13:13:52

This confuses me just a bit. Isn't passing a reference pass-by-reference?

@Huy-Anh Hoang 2017-10-10 21:09:32

The author means that by passing a reference, you're passing a reference value (another way to think of it is passing the value of the memory address). So that's why if you redeclare the object, the original doesn't change, because you're creating a new object at a different memory location. If you change a property, the original object changes because you changed it at the original memory location (that was not reassigned).

@geg 2020-07-02 00:07:35

The phrase "passing a reference by value" seems unnecessarily confusing and redundant. When passing a reference of course some value must be passed. While technically true, it is likely the default assumption of most people that anything is passed by value unless otherwise specified. So of course a reference is passed by value unless it itself is passed by reference (kind of like a pointer to a pointer in C), but in this case Javascript doesn't even support that so I don't think it helps make the concept any clearer

@Shog9 2020-07-02 00:19:02

The point of confusion with JavaScript is that it provides no choice in the matter, @geg: complex types will always be handled indirectly, simple types always directly. There's no way to get a reference to an integer, nor prevent passing a reference to a tuple. This ... Is just going to be awkward sometimes.

@Jack Sleight 2009-02-05 21:36:56

There's some discussion about the use of the term "pass by reference" in JavaScript here, but to answer your question:

A object is automatically passed by reference, without the need to specifically state it

(From the article mentioned above.)

@C Perkins 2016-12-23 19:15:07

The linked article no longer includes that statements and avoids using "pass by reference" altogether.

@user985399 2019-06-05 13:13:46

The value is a reference

@georgeawg 2018-07-25 15:47:13

JavaScript passes primitive types by value and object types by reference

Now, people like to bicker endlessly about whether "pass by reference" is the correct way to describe what Java et al. actually do. The point is this:

  1. Passing an object does not copy the object.
  2. An object passed to a function can have its members modified by the function.
  3. A primitive value passed to a function cannot be modified by the function. A copy is made.

In my book that's called passing by reference.

Brian Bi - Which programming languages are pass by reference?


Here is a rebuttal to this:

There is no "pass by reference" available in JavaScript.

@nasch 2019-03-27 17:03:19

@Amy Because that's describing pass by value, not pass by reference. This answer is a good one that shows the difference:

@Amy 2019-03-27 17:32:42

@nasch I understand the difference. #1 and #2 are describing pass-by-ref semantics. #3 is describing pass-by-value semantics.

@nasch 2019-03-27 17:35:42

@Amy 1, 2, and 3 are all consistent with pass by value. To have pass by reference you would also need 4: assigning the reference to a new value inside the function (with the = operator) also reassigns the reference outside the function. This is not the case with Javascript, making it exclusively pass by value. When passing an object, you pass a pointer to the object, and you pass that pointer by value.

@Amy 2019-03-27 17:38:52

That isn't generally what is meant by "pass-by-reference". You've satisfied my query, and I disagree with you. Thanks.

@Jörg W Mittag 2020-06-01 10:53:11

"In my book that's called passing by reference." – In every single compiler book, interpreter book, programming language theory book, and computer science book ever written, it is not.

@Tim Goodman 2011-03-15 16:38:23

It's always pass by value, but for objects the value of the variable is a reference. Because of this, when you pass an object and change its members, those changes persist outside of the function. This makes it look like pass by reference. But if you actually change the value of the object variable you will see that the change does not persist, proving it's really pass by value.


function changeObject(x) {
  x = { member: "bar" };
  console.log("in changeObject: " + x.member);

function changeMember(x) {
  x.member = "bar";
  console.log("in changeMember: " + x.member);

var x = { member: "foo" };

console.log("before changeObject: " + x.member);
console.log("after changeObject: " + x.member); /* change did not persist */

console.log("before changeMember: " + x.member);
console.log("after changeMember: " + x.member); /* change persists */


before changeObject: foo
in changeObject: bar
after changeObject: foo

before changeMember: foo
in changeMember: bar
after changeMember: bar

@artur 2011-05-22 21:29:09

Hi Tim, thanks for the excellent response. I have a tiny suggestion for clarity purposes - can you please invert either the order of the function declarations or the order of callings to match each other? It took me a while to realize that the output wasn't contracting your conclusion! :)

@deworde 2011-07-18 08:56:45

@daylight: Actually, you're wrong; if it was passed by const ref trying to do changeObject would cause an error, rather than just failing. Try assigning a new value to a const reference in C++ and the compiler rejects it. In user terms, that's the difference between pass by value and pass by const reference.

@Tim Goodman 2011-07-19 21:47:44

@daylight: It's not constant ref. In changeObject, I've changed x to contain a reference to the new object. x = {member:"bar"}; is equivalent to x = new Object(); x.member = "bar"; What I'm saying is also true of C#, by the way.

@Tim Goodman 2011-07-19 21:55:13

@daylight: For C#, you can see this from outside the function, if you use the ref keyword you can pass the reference by reference (instead of the default of passing the reference by value), and then the change to point to a new Object() will persist.

@Aditya M P 2013-07-28 10:01:31

okay, I get it now... but ;_; why does JavaScript do that?! Why does it tread an ambiguous line between "pass by reference/value"?

@Tim Goodman 2013-07-28 11:11:19

@adityamenon It's hard to answer "why", but I would note that the designers of Java and C# made a similar choice; this isn't just some JavaScript weirdness. Really, it's very consistently pass-by-value, the thing that makes it confusing for people is that a value can be a reference. It's not much different than passing a pointer around (by value) in C++ and then dereferencing it to set the members. No one would be surprised that that change persists. But because these languages abstract away the pointer and silently do the dereferencing for you, people get confused.

@Tim Goodman 2013-07-28 11:27:15

In other words, the confusing thing here isn't pass-by-value/pass-by-reference. Everything is pass-by-value, full stop. The confusing thing is that you cannot pass an object, nor can you store an object in a variable. Every time you think you're doing that, you're actually passing or storing a reference to that object. But when you go to access its members, there's a silent dereferencing that happens, that perpetuates the fiction that your variable held the actual object.

@Aditya M P 2013-07-28 12:08:12

Very eloquent comments that opened my eyes to something really cool and unknown to me in JS: all object manipulation happens via pointers to those objects, I see very little about this being talked (at least where I read)! When we talk about prototypes, those are actually references to 'parent' objects, right? So are they internally references to references? Do these mysterious beings we call references have a different internal name?

@chiccodoro 2014-05-02 09:23:52

As you correctly state, "everything is pass-by-value, full stop"! The fact that objects are stored as references is not constraint to passing parameters at all. To make the point even clearer you might add an example like this: var x = { member: 'foo' }; var y = x; y.member = 'bar';. will have the new value even though we did not pass parameters at all. Nobody will claim that variable assignment was done "by reference" (I hope)

@Peng 2018-04-07 22:56:35

I think this is the same as parameter passing in Java.

@miguelr 2019-04-20 06:06:32

The MDN docs explain it clearly, without being too verbose:

The parameters of a function call are the function's arguments. Arguments are passed to functions by value. If the function changes the value of an argument, this change is not reflected globally or in the calling function. However, object references are values, too, and they are special: if the function changes the referred object's properties, that change is visible outside the function, (...)


@Phil Mander 2015-02-13 11:00:24

Think of it like this: It's always pass by value. However, the value of an object is not the object itself, but a reference to that object.

Here is an example, passing a number (a primitive type)

function changePrimitive(val) {
    // At this point there are two '10's in memory.
    // Changing one won't affect the other
    val = val * 10;
var x = 10;
// x === 10

Repeating this with an object yields different results:

function changeObject(obj) {
    // At this point there are two references (x and obj) in memory,
    // but these both point to the same object.
    // changing the object will change the underlying object that
    // x and obj both hold a reference to.
    obj.val = obj.val * 10;
var x = { val: 10 };
// x === { val: 100 }

One more example:

function changeObject(obj) {
    // Again there are two references (x and obj) in memory,
    // these both point to the same object.
    // now we create a completely new object and assign it.
    // obj's reference now points to the new object.
    // x's reference doesn't change.
    obj = { val: 100 };
var x = { val: 10 };
// x === { val: 10}

@DannyNiu 2017-07-28 13:17:37

For programming language lawyers, I've went through the following sections of ECMAScript 5.1 (which is easier to read than the latest edition), and go as far as asking it on the ECMAScript mailing list.

TL;DR: Everythings're passed by value, but properties of Objects are references, and the definition of Object is creepily lacking in the standard.

Construction of Argument Lists

Section 11.2.4 "Argument Lists" says the following on producing a argument list consisting of only 1 argument:

The production ArgumentList : AssignmentExpression is evaluated as follows:

  1. Let ref be the result of evaluating AssignmentExpression.
  2. Let arg be GetValue(ref).
  3. Return a List whose sole item is arg.

The section also enumerate cases where argument list has 0 or >1 arguments.

Thus, everything's are passed by reference.

Access of Object Properties

Section 11.2.1 "Property Accessors"

The production MemberExpression : MemberExpression [ Expression ] is evaluated as follows:

  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be GetValue(baseReference).
  3. Let propertyNameReference be the result of evaluating Expression.
  4. Let propertyNameValue be GetValue(propertyNameReference).
  5. Call CheckObjectCoercible(baseValue).
  6. Let propertyNameString be ToString(propertyNameValue).
  7. If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false.
  8. Return a value of type Reference whose base value is baseValue and whose referenced name is propertyNameString, and whose strict mode flag is strict.

Thus, properties of Objects are always available as reference.

On Reference

It is described in section 8.7 "The Reference Specification Type", that references are not real types in the language - they're only used to describe the behavior of the delete, the typeof, and the assignment operators.

Definition of "Object"

It is defined in 5.1 edition that "An Object is a collection of properties". Therefore, we can infer, that the value of the object is the collection, but as to what is the value of the collection is poorly defined in the spec, and requires a bit of effort to understand.

@David A. Gray 2017-10-01 06:11:01

It never ceases to amaze me how many people get confused by the distinctions among arguments passed by value, arguments passed by reference, operations on whole objects, and operations on their properties. In 1979, I didn't get my degree in computer science, electing instead to add 15 hours or so of CS electives to my MBA program. Nevertheless, it soon became clear to me that my grasp of these concepts was at least as good as that held by any of my colleagues who had degrees in computer science or mathematics. Study Assembler, and it will become quite clear.

@geg 2015-09-26 04:06:20

Consider the following:

  1. Variables are pointers to values in memory.
  2. Reassigning a variable merely points that pointer at a new value.
  3. Reassigning a variable will never affect other variables that were pointing at that same object

So, forget about "pass by reference/value" don't get hung up on "pass by reference/value" because:

  1. The terms are only used to describe the behavior of a language, not necessarily the actual underlying implementation. As a result of this abstraction, critical details that are essential for a decent explanation are lost, which inevitably leads to the current situation where a single term doesn't adequately describe the actual behavior and supplementary info has to be provided
  2. These concepts were not originally defined with the intent of describing javascript in particular and so I don't feel compelled to use them when they only add to the confusion.

To answer your question: pointers are passed.

// code
var obj = {
    name: 'Fred',
    num: 1

// illustration
(obj) ---- {}

// code = 'George';

// illustration

(obj) ---- {} ----- 'George'

// code
obj = {};

// illustration

(obj)      {} ----- 'George'
  |          \
  |           \
 { }            1

// code
var obj = {
    text: 'Hello world!'

/* function parameters get their own pointer to 
 * the arguments that are passed in, just like any other variable */

// illustration
(caller scope)        (someFunc scope)
           \             /
            \           /
             \         /
              \       /
               \     /
                 { }
            'Hello world'

Some final comments:

  • It's tempting to think that primitives are enforced by special rules while objects are not, but primitives are simply the end of the pointer chain.
  • As a final example, consider why a common attempt to clear an array doesn't work as expected.

var a = [1,2];
var b = a;

a = [];
console.log(b); // [1,2]
// doesn't work because `b` is still pointing at the original array

@Michael Hoffmann 2017-03-04 21:43:47

Follow-up questions for extra credit ;) How does garbage collection work? If I cycle a variable through a million {'George', 1} values, but only use one of them at a time, then how are the others managed? And what happens when I assign a variable to the value of another variable? Am I then pointing to a pointer, or pointing to the pointee of the right operand? Does var myExistingVar = {"blah", 42}; var obj = myExistingVar; result in obj pointing to {"blah", 42}, or to myExistingVar?

@geg 2017-03-14 04:14:54

@MichaelHoffmann These deserve their own SO questions and are probably already answered better than I can manage. That being said, 1) I ran a memory profile in the browser dev tools for a loop function such as the one you described and saw spikes in memory usage throughout the looping process. This would seem to indicate that new identical objects are indeed being created in each iteration of the loop. When the spikes suddenly fall, the garbage collector just cleaned up a group of these unused objects.

@geg 2017-03-14 04:16:04

@MichaelHoffmann 2) Regarding something like var a = b, javascript does not provide a mechanism for using pointers and so a variable can never point to a pointer (as you can in C), although the underlying javascript engine undoubtedly uses them. So...var a = b will point a "to the pointee of the right operand"

@Michael Hoffmann 2017-03-14 05:39:16

I asked question #1 here (specifically about Chrome because the implementation is likely different in every browser) and I'm still trying to think of how to word question #2. Any help is appreciated.

@C Perkins 2017-05-30 19:50:07

There is no need to forget about "pass by reference/value"! These terms have historical meanings that describe exactly what you attempt to describe. If we throw out the historical terms and definitions and become too lazy to learn what they originally meant, then we lose the ability to communicate effectively between generations. There would be no good way discuss the differences between different languages and systems. Instead, new programmers need to learn and understand the traditional terms and why and were they came from. Otherwise, we collectively lose knowledge and understanding.

@C Perkins 2016-12-23 18:43:29

Semantics!! Setting concrete definitions will necessarily make some answers and comments incompatible since they are not describing the same thing even when using the same words and phrases, but it is critical to get past the confusion (especially for new programmers).

First of all, there are multiple levels of abstraction that not everyone seems to grasp. Newer programmers who have learned on 4th or 5th generation languages may have difficulty wrapping their mind around concepts familiar to assembly or C programmers not phased by pointers to pointers to pointers. Pass-by-reference does not simply mean the ability to change a referenced object using a function parameter variable.

Variable: Combined concept of a symbol which references a value at a particular location in memory. This term is usually too loaded to be used alone in discussing details.

Symbol: Text string used to refer to variable (i.e. variable's name).

Value: Particular bits stored in memory and referenced using variable's symbol.

Memory location: Where a variable's value is stored. (The location itself is represented by a number separate from the value stored at the location.)

Function parameter: Variable declared in a function definition, used for referencing variables passed to the function.

Function argument: Variable outside the function which is passed to the function by the caller.

Object variable: Variable whose basic underlying value is not the "object" itself, rather its value is a pointer (memory location value) to another location in memory where the object's actual data is stored. In most higher-generation languages, the "pointer" aspect is effectively hidden by automatic de-referencing in various contexts.

Primitive variable: Variable whose value IS the actual value. Even this concept can be complicated by auto-boxing and object-like contexts of various languages, but the general ideas is that the variable's value IS the actual value represented by the variable's symbol rather than a pointer to another memory location.

Function arguments and parameters are not the same thing. Also, a variable's value is not the variable's object (as already pointed out by various people, but apparently ignored). These distinctions are critical to proper understanding.

Pass-by-value or Call-by-sharing (for objects): The function argument's value is COPIED to another memory location which is referenced by the function's parameter symbol (regardless of whether it's on the stack or heap). In other words, the function parameter received a copy of the passed argument's value... AND (critical) the argument's value IS NEVER UPDATED / ALTERED / CHANGED by the calling function. Remember, an object variable's value is NOT the object itself, rather it is the pointer to the object, so passing an object variable by value copies the pointer to the function parameter variable. The function parameter's value points to the exact same object in memory. The object data itself can be altered directly via the function parameter, BUT the function argument's value IS NEVER UPDATED, so it will continue to point to the same object throughout and even after the function call (even if its object's data was altered or if the function parameter is assigned a different object altogether). It is incorrect to conclude that the function argument was passed by reference just because the referenced object is updatable via the function parameter variable.

Call / Pass-by-reference: The function argument's value can/will be updated directly by the corresponding function parameter. If it helps, the function parameter becomes an effective "alias" for the argument--they effectively refer to the same value at the same memory location. If a function argument is an object variable, the ability to change the object's data is no different than the pass-by-value case since the function parameter will still point to the same object as the argument. But in the object variable case, if the function parameter is set to a completely different object, then the argument will likewise also point to the different object--this does not happen in the pass-by-value case.

JavaScript does not pass by reference. If you read closely, you will realize that all contrary opinions misunderstand what is meant by pass-by-value and they falsely conclude that the ability to update an object's data via the function parameter is synonymous to "pass-by-value".

Object clone/copy: A new object is created and the original object's data is copied. This can be a deep copy or shallow copy, but the point is that a new object is created. Creating a copy of an object is a separate concept from pass-by-value. Some languages distinguish between class object and structs (or the like), and may have different behavior for passing variables of the different types. But JavaScript does not do anything like this automatically when passing object variables. But the absence of automatic object cloning does not translate to pass-by-reference.

@steviejay 2016-10-29 14:50:30

I've read through these answers multiple times, but didn't REALLY get it until I learned about the technical definition of "Call by sharing" as termed by Barbara Liskov

The semantics of call by sharing differ from call by reference in that assignments to function arguments within the function aren't visible to the caller (unlike by reference semantics)[citation needed], so e.g. if a variable was passed, it is not possible to simulate an assignment on that variable in the caller's scope. However, since the function has access to the same object as the caller (no copy is made), mutations to those objects, if the objects are mutable, within the function are visible to the caller, which may appear to differ from call by value semantics. Mutations of a mutable object within the function are visible to the caller because the object is not copied or cloned — it is shared.

That is, parameter references are alterable if you go and access the parameter value itself. On the other hand, assignment to a parameter will disappear after evaluation, and is non-accessible to the function caller.

@Scott Marcus 2018-04-05 17:33:41

No, whether an object is mutable or not isn't really the issue. Everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

@Sanjeev 2019-06-17 17:03:22

What she's describing is passing a reference BY-VALUE. There is no reason to introduce new terminology.

@Narayon 2016-10-19 12:07:22

In a low level language, if you want to pass a variable by reference you have to use a specific syntax in the creation of the function:

int myAge = 14;
function increaseAgeByRef(int &age) {
  *age = *age + 1;

The &age is a reference to myAge, but if you want the value you have to convert the reference, using *age.

Javascript is a high level language that does this conversion for you. So, although objects are passed by reference, the language converts the reference parameter to the value. You don't need to use &, on the function definition, to pass it by reference, neither *, on the function body, to convert the reference to the value, JS does it for you.

That's why when you try to change an object inside a function, by replacing it's value (i.e. age = {value:5}), the change doesn't persist, but if you change it's properties (i.e. age.value = 5), it does.

Learn more

@zangw 2015-12-30 02:20:13

In JavaScript, the type of the value solely controls whether that value will be assigned by value-copy or by reference-copy.

Primitive values are always assigned/passed by value-copy:

  • null
  • undefined
  • string
  • number
  • boolean
  • symbol in ES6

Compound values are always assigned/passed by reference-copy

  • objects
  • arrays
  • function

For example

var a = 2;
var b = a; // `b` is always a copy of the value in `a`
a; // 2
b; // 3

var c = [1,2,3];
var d = c; // `d` is a reference to the shared `[1,2,3]` value
d.push( 4 );
c; // [1,2,3,4]
d; // [1,2,3,4]

In the above snippet, because 2 is a scalar primitive, a holds one initial copy of that value, and b is assigned another copy of the value. When changing b, you are in no way changing the value in a.

But both c and d are separate references to the same shared value [1,2,3], which is a compound value. It's important to note that neither c nor d more "owns" the [1,2,3] value -- both are just equal peer references to the value. So, when using either reference to modify (.push(4)) the actual shared array value itself, it's affecting just the one shared value, and both references will reference the newly modified value [1,2,3,4].

var a = [1,2,3];
var b = a;
a; // [1,2,3]
b; // [1,2,3]

// later
b = [4,5,6];
a; // [1,2,3]
b; // [4,5,6]

When we make the assignment b = [4,5,6], we are doing absolutely nothing to affect where a is still referencing ([1,2,3]). To do that, b would have to be a pointer to a rather than a reference to the array -- but no such capability exists in JS!

function foo(x) {
    x.push( 4 );
    x; // [1,2,3,4]

    // later
    x = [4,5,6];
    x.push( 7 );
    x; // [4,5,6,7]

var a = [1,2,3];

foo( a );

a; // [1,2,3,4]  not  [4,5,6,7]

When we pass in the argument a, it assigns a copy of the a reference to x. x and a are separate references pointing at the same [1,2,3] value. Now, inside the function, we can use that reference to mutate the value itself (push(4)). But when we make the assignment x = [4,5,6], this is in no way affecting where the initial reference a is pointing -- still points at the (now modified) [1,2,3,4] value.

To effectively pass a compound value (like an array) by value-copy, you need to manually make a copy of it, so that the reference passed doesn't still point to the original. For example:

foo( a.slice() );

Compound value (object, array, etc) that can be passed by reference-copy

function foo(wrapper) {
    wrapper.a = 42;

var obj = {
    a: 2

foo( obj );

obj.a; // 42

Here, obj acts as a wrapper for the scalar primitive property a. When passed to foo(..), a copy of the obj reference is passed in and set to the wrapperparameter. We now can use the wrapper reference to access the shared object, and update its property. After the function finishes, obj.a will see the updated value 42.


@C Perkins 2017-05-30 19:11:57

You first state "Compound values are always assigned/passed by reference-copy", and then you state "assigns a copy of the a reference to x". In the case of what you call a "compound value", the actual variable value IS the reference (i.e. the memory pointer). Just as you explained, the reference is copied... so the variables value is copied, again emphasizing that the REFERENCE IS THE VALUE. That means JavaScript is pass-by-value for all types. Pass-by-value means passing a copy of the variables value. It does not matter that the value is a references to an object / array.

@Scott Marcus 2018-04-05 17:32:16

You introduce new terminology (value-copy/reference-copy) and that just makes things more complex. There are just copies, period. If you pass a primitive you passed a copy of the actual primitive data, if you pass an object, you passed a copy of the object's memory location. That's all you need to say. Anything more just further confuses people.

@lyslim 2015-01-09 04:54:36

I would say it is pass-by-copy -

Consider arguments and variable objects are objects created during the execution context created in the beginning of function invocation - and your actual value/reference passed into the function just get stored in this arguments + variable objects.

Simply speaking, for primitive types, the values get copied in the beginning of function call, for object type, the reference get copied.

@Scott Marcus 2018-04-05 17:29:43

"pass-by-copy" === pass by value

@John Sonderson 2014-11-01 12:43:24

Passing arguments to a function in JavaScript is analogous to passing parameters by pointer value in C:

The following C program demonstrates how arguments
to JavaScript functions are passed in a way analogous
to pass-by-pointer-value in C. The original JavaScript
test case by @Shog9 follows with the translation of
the code into C. This should make things clear to
those transitioning from C to JavaScript.

function changeStuff(num, obj1, obj2)
    num = num * 10;
    obj1.item = "changed";
    obj2 = {item: "changed"};

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);

This produces the output:


#include <stdio.h>
#include <stdlib.h>

struct obj {
    char *item;

void changeStuff(int *num, struct obj *obj1, struct obj *obj2)
    // make pointer point to a new memory location
    // holding the new integer value
    int *old_num = num;
    num = malloc(sizeof(int));
    *num = *old_num * 10;
    // make property of structure pointed to by pointer
    // point to the new value
    obj1->item = "changed";
    // make pointer point to a new memory location
    // holding the new structure value
    obj2 = malloc(sizeof(struct obj));
    obj2->item = "changed";
    free(num); // end of scope
    free(obj2); // end of scope

int num = 10;
struct obj obj1 = { "unchanged" };
struct obj obj2 = { "unchanged" };

int main()
    // pass pointers by value: the pointers
    // will be copied into the argument list
    // of the called function and the copied
    // pointers will point to the same values
    // as the original pointers
    changeStuff(&num, &obj1, &obj2);
    printf("%d\n", num);
    return 0;

@Danail Nachev 2015-04-07 00:05:43

I don't think this is the case in JavaScript: ```javascript var num = 5;

@Jörg W Mittag 2020-06-01 10:51:54

@DanailNachev: While that may be technically true, the difference is only observable for mutable objects which ECMAScript primitives aren't.

@Mukund Kumar 2014-10-28 13:45:26

  1. primitive type variable like string,number are always pass as pass by value.
  2. Array and Object is passed as pass by reference or pass by value based on these two condition.

    • if you are changing value of that Object or array with new Object or Array then it is pass by Value.

      object1 = {item: "car"}; array1=[1,2,3];

    here you are assigning new object or array to old are not changing the value of property of old it is pass by value.

    • if you are changing a property value of an object or array then it is pass by Reference.

      object1.key1= "car"; array1[0]=9;

    here you are changing a property value of old are not assigning new object or array to old it is pass by reference.


    function passVar(object1, object2, number1) {

        object1.key1= "laptop";
        object2 = {
            key2: "computer"
        number1 = number1 + 1;

    var object1 = {
        key1: "car"
    var object2 = {
        key2: "bike"
    var number1 = 10;

    passVar(object1, object2, number1);

Output: -

@John Sonderson 2014-10-29 11:45:11

The assignment operator is not to be confused with a function call. When you assign new data to an existing variable the reference count of the old data decreases and new data is associated with the old variable. Basically, the variable ends up pointing to the new data. The same is true of property variables. Since these assignments are not function calls they have nothing to do with pass-by-value or pass-by-reference.

@Scott Marcus 2018-04-05 17:28:59

No, everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

@dpp 2014-09-16 09:19:53

My simple way to understand this...

  • When calling a function, you are passing the content (reference or value) of the argument variables, not the the variables themselves.

    var var1 = 13;
    var var2 = { prop: 2 };
    //13 and var2's content (reference) are being passed here
    foo(var1, var2); 
  • Inside the function, parameter variables, inVar1 and inVar2, receive the contents being passed.

    function foo(inVar1, inVar2){
        //changing contents of inVar1 and inVar2 won't affect variables outside
        inVar1 = 20;
        inVar2 = { prop: 7 };
  • Since inVar2 received the reference of { prop: 2 }, you can change the value of the object's property.

    function foo(inVar1, inVar2){
        inVar2.prop = 7; 

@lid 2014-05-17 01:01:14

The most succinct explanation I found was in the AirBNB style guide:

  • Primitives: When you access a primitive type you work directly on its value

    • string
    • number
    • boolean
    • null
    • undefined


var foo = 1,
    bar = foo;

bar = 9;

console.log(foo, bar); // => 1, 9
  • Complex: When you access a complex type you work on a reference to its value

    • object
    • array
    • function


var foo = [1, 2],
    bar = foo;

bar[0] = 9;

console.log(foo[0], bar[0]); // => 9, 9

I.e. effectively primitive types are passed by value, and complex types are passed by reference.

@Scott Marcus 2018-04-05 17:26:20

No, everything is always passed by value. It just depends on what you are passing (a value or a reference). See this.

Related Questions

Sponsored Content

95 Answered Questions

[SOLVED] How can I remove a specific item from an array?

  • 2011-04-23 22:17:18
  • Walker
  • 6845109 View
  • 8423 Score
  • 95 Answer
  • Tags:   javascript arrays

28 Answered Questions

[SOLVED] What does "use strict" do in JavaScript, and what is the reasoning behind it?

61 Answered Questions

[SOLVED] How do I include a JavaScript file in another JavaScript file?

53 Answered Questions

86 Answered Questions

[SOLVED] How do JavaScript closures work?

42 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

87 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

3 Answered Questions

26 Answered Questions

[SOLVED] How do I pass a variable by reference?

54 Answered Questions

Sponsored Content