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?

30 comments

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

Example:

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);
changeObject(x);
console.log("after changeObject: " + x.member); /* change did not persist */

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

Output:

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';. x.foo 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, (...)

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Description

@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?


Update

Here is a rebuttal to this:

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

@nasch 2019-01-15 18:14:59

That guy's book is wrong.

@Amy 2019-03-27 13:55:34

@nasch Looks right to me. Care to elaborate?

@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: stackoverflow.com/a/3638034/3307720

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

@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

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

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

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

@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;
changePrimitive(x);
// 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 };
changeObject(x);
// 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 };
changeObject(x);
// x === { val: 10}

@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);

console.log(num);
console.log(obj1.item);    
console.log(obj2.item);

This produces the output:

10
changed
unchanged
  • If it was pure pass by value, then changing obj1.item would have no effect on the obj1 outside of the function.
  • If it was pure pass by 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.

@student 2017-08-10 12:43:08

sharing what I know of references in javascript

In Javascript, objects are stored as references:

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.

@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
               'Fred'
              /
             /
(obj) ---- {}
             \
              \
               1


// code
obj.name = 'George';


// illustration
                 'Fred'


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


// code
obj = {};

// illustration
                 'Fred'


(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 */
someFunc(obj);


// 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) stackoverflow.com/q/42778439/539997 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.

@geg 2017-06-01 22:06:01

@CPerkins Fair point. I tried to clarify.

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

@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;
increaseAgeByRef(myAge);
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

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

Javascript is always pass-by-value, everything is of value type. Objects are values, 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(x.foo);
x.foo = 12;
alert(x.foo);

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"; x.foo = 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, stackoverflow.com/questions/373419/…, 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.

@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`
b++;
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.

Source

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

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

My 2 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.

object2.name = 'Fred';
console.log(favoriteObject.name) // logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // 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 strings are immutable and we didn't mutate it. All we did was "RE ASSIGN" favoriteString 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, actually... we did, we assigned 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.

Now, on to functions and passing parameters.... When you call a function, and pass a parameter, what you are essentially doing is "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
myFunc(myString); 

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

OK, now lets 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
otherObj = {
    firstName: 'Jack',
    lastName: 'Frost'
};

// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object no longer mutates 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 no longer mutates the other
}

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

// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject
myFunc(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 also means assignment. They are the same and the 2 variables are connected in exactly the same way.

The only time that modifying a variable affects a different variable is when the underlying object is mutated.

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';

myFunc(myString);
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*/; copy.id="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.

@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);
console.log(num);
console.log(obj1.item);    
console.log(obj2.item);

This produces the output:

10
changed
unchanged
*/

#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);
    puts(obj1.item);
    puts(obj2.item);
    return 0;
}

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

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

@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 one.you are not changing the value of property of old object.so 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 object.you are not assigning new object or array to old one.so it is pass by reference.

Code

    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);
    console.log(object1.key1);
    console.log(object2.key2);
    console.log(number1);

Output: -
    laptop
    bike
    10

@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

E.g.:

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

E.g.:

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.

@lefakir 2013-06-27 17:46:11

In some case, this may be helpful to alter anArg:

function alterMyArg(func) {
    // process some data
    // ...
    func(data);
}

alertMyArg(function(d) {anArg = d;});

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

There's some discussion about the use of the term "pass by reference" in JS 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.

@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;

willNotChange(x);

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

function willChange(y) {

y.num = 2;

}

var y = {num: 2000}; 

willChange(y);
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) 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.

@Jack 2012-05-05 14:32:23

I have found the extend method of the Underscore.js library very useful when I want to pass in an object as a parameter which may either be modified or replaced entirely.

function replaceOrModify(aObj) {
  if (modify) {

    aObj.setNewValue('foo');

  } else {

   var newObj = new MyObject();
   // _.extend(destination, *sources) 
   _.extend(newObj, aObj);
  }
}

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

Object outside a function is passed into a function by giving a reference to the outside obejct. 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.

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

One thing I still cannot figure out. Check code below. Any thoughts?

function A() {}
A.prototype.foo = function() {
    return 'initial value';
}


function B() {}
B.prototype.bar = A.prototype.foo;

console.log(A.prototype.foo()); //initial value
console.log(B.prototype.bar()); //initial value

A.prototype.foo = function() {
    return 'changed now';
}

console.log(A.prototype.foo()); //changed now
console.log(B.prototype.bar()); //Why still 'initial value'???

@raddevus 2011-05-17 14:06:00

I have explained exactly what you've done and what it means, but these comments do not allow me to post over 600 chars or whatever, so I've posted it as an answer below. Please check it out and comment. thx ~daylight

@igor 2011-05-18 11:03:30

So it seems that B.prototype.bar = A.prototype.foo; is assigned by reference, but latter A.prototype.foo = function() {...} is changing the value of the foo property of A.prototype and breaks the reference. B.prototype.bar still holds the reference to the same first function.

@Greg 2016-12-10 01:01:30

Setting one function equal to another is not an assignment by reference. 'foo' and 'bar' are just functions that are members of objects A and B

@Greg 2016-12-12 16:32:41

Here's a demo of implementing the function as a single array member instead. An array will copy by reference, but a function will copy by value. jsfiddle.net/ug04ks33

@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, VB or Delphi. I can't say how they handle objects and primitives exactly, but I know of VB 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 preceeded 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 jsfiddle.net/rdarc 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

@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, 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 JS 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).

Related Questions

Sponsored Content

38 Answered Questions

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

79 Answered Questions

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

86 Answered Questions

[SOLVED] How do JavaScript closures work?

3 Answered Questions

52 Answered Questions

26 Answered Questions

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

26 Answered Questions

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

79 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5716438 View
  • 7108 Score
  • 79 Answer
  • Tags:   javascript arrays

54 Answered Questions

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

Sponsored Content