aspose file tools*
The moose likes HTML, CSS and JavaScript and the fly likes Is JavaScript really  Pass-By-Reference? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » HTML, CSS and JavaScript
Bookmark "Is JavaScript really  Pass-By-Reference?" Watch "Is JavaScript really  Pass-By-Reference?" New topic
Author

Is JavaScript really Pass-By-Reference?

Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Pardon my confusion, but there is something very fundamental that is bugging me about JavaScript.

You see, I was borne and raised in Java and I know by heart that Java is a strictly pass-by-value language. That means when I pass a variable that is an object reference into a method parameter, Java actually makes a copy of the object reference variable inside the method for it to use. Ultimately it still points to the same object, but now I have two references now pointing to it (one inside the method and the original one outside the method.)

However, in JavaScript, every guide I read says that when passing JavaScript object variables through method parameters - it does it through pass-by-reference. Literal JavaScript datatypes are, of course, pass-by-value (and I get that perfectly.)

This leads me to a fundamental question - isn't a JavaScript object datatype represented by variables through references in the first place - much like Java?

For example:



Is the original outsideObject variable a "reference" to my instantiated JavaScript object? Then doesn't it function just like Java, where when it call changeObject(methodObject) - it makes a copy of the "reference" variable (which becomes variable methodObject)? Wouldn't this constitute as pass-by-value then - because it is making a "copy" of the reference variable?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Well, yes, that code functions just like Java -- and if you wrote that code in Java it would do exactly the same thing. But that's because it doesn't test whether pass-by-reference is happening at all. You never try to change the reference from inside the method. Here's some code which does test that:



In a pass-by-value language you would see "unchanged", but in a pass-by-reference language you would see "something else".
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

[Edit: great minds think alike -- Paul posted that while I was composing. but I'll let my example stand as well.]

Firstly, JavaScript is not Java, has nothing to do with Java, and thinking that it does have something to do with Java will lead to nothing but pain and misery. Except for the lamentable decision to name the language JavaScript back when Java was the new hotness, they have nothing whatsoever to do with each other.

That said, your expectations about how passing object references works is correct. What pass-by-value means and what pass-by-reference means seems to be as malleable as the definition of "application server" -- in other words, no one agrees on what they actually mean.

You can try this yourself with the following code:
Would you expect the reference in o1 to be over-written by the function call?


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Paul Clapham wrote:Well, yes, that code functions just like Java -- and if you wrote that code in Java it would do exactly the same thing. But that's because it doesn't test whether pass-by-reference is happening at all. You never try to change the reference from inside the method. Here's some code which does test that:



In a pass-by-value language you would see "unchanged", but in a pass-by-reference language you would see "something else".


I guess we can break this down even more fundamentally then --- into terms of just simple variable assignments ("="):

In pass-by-reference language paradigms (such as object handling in JavaScript):
oneObject = anotherObject - triggers pass-by-reference itself because oneObject becomes "aliased" to anotherObject by the "=" sign. There is no copying of another reference data at all - so the total count of "reference" data in this specific scope we would be dealing with would only be one.

In contrast to a strict pass-by-value language paradigm (such as everything in Java):
oneObject = anotherObject - would make of a copy of the reference anotherObject is pointing to, and assign it to oneObject - so in total there are now a total count of two references in this scope.

However - what is the similar in both scenarios above is that since we are dealing with variable "references" (aka Reference Type variables) to objects to begin with - there is still really only one real object in memory we are dealing with in each of these scenarios (if we assume the anotherObject variable in both cases actually pointed to an instantiated object).

Am I getting all this right? I know I'm getting real nit-picky right now - but I want to get it straight once and for all....
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

Perry Terrance wrote: because oneObject becomes "aliased" to anotherObject by the "=" sign.

I would not put it that way, nor think of it that way. That makes it sounds like somehow anotherObject is the "real" reference to the object, and oneObject is somehow a "faux" or "aliased" reference. Not so. After the assignment, both variables reference the object and whether one was first or not makes no difference.

There is no copying of another reference data at all

What's copied is the reference, not the object.

In contrast to a strict pass-by-value language paradigm (such as everything in Java):
oneObject = anotherObject - would make of a copy of the reference anotherObject is pointing to, and assign it to oneObject - so in total there are now a total count of two references in this scope.

Absolutely incorrect. No such thing happens in Java. The reference is simply copied and there still exists only a single object that both references are pointing to.

Am I getting all this right?

Nope.

In any case, the whole "pass-by-xxx" thing has nothing to do with assignments, but with parameter passing.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Bear Bibeault wrote:
Perry Terrance wrote:
In contrast to a strict pass-by-value language paradigm (such as everything in Java):
oneObject = anotherObject - would make of a copy of the reference anotherObject is pointing to, and assign it to oneObject - so in total there are now a total count of two references in this scope.

Absolutely incorrect. No such thing happens in Java. The reference is simply copied and there still exists only a single object that both references are pointing to.



But I think we're talking about the same thing here. Note: I said two references - not objects, so there does exist two references.

http://www.javaranch.com/campfire/StoryPassBy.jsp

This JavaRanch Campfire article perfectly describes what I'm talking about:

http://www.javaranch.com/campfire/StoryPassBy.jsp wrote:SO... what about Reference Variables (remote controls)? How does THAT work?

Not so tricky, in fact the rule is the same.

References do the same thing. You get a copy of the reference.

So if I say:

Cat A = new Cat();

Cat B = A;

The remote control in A is copied. Not the object it refers to.
You've still got just one Cat object.
But now you have two different references (remote controls) controlling the same Cat object.


So there ARE two different references (variable oneObject and variable anotherObject), but only one object that both points to. Yet the rule of Java's pass-by-value also remains in tact here because its simply COPYING the reference of variable anotherObject and putting it into variable oneObject.

------------------------------------------------------------------------------

Next, for what you said about pass-by-value only pertaining to parameters passing only - what I'm getting confused here is this following statements from that same JavaRanch article which pertains pass-by-value to even simple assignments ("="). This was where I came to believe that pass-by-value is tied to the natural paradigm of the language (in this case Java) itself in general - not just specifically tied-to method param passing.

http://www.javaranch.com/campfire/StoryPassBy.jsp wrote:So if a Java variable is a cup, with a value in it, what does it mean to "pass" a variable to a method? And are primitives and references treated the same way?

We'll get there, but first let's start with simple assignment.

What does it mean to say:

1) int x = 3;

2) int y = x;

In line 1, a cup called x, of size int, is created and given the value 3.

In line 2, a cup called y, of size int, is created and given the value... 3.

The x variable is not affected!

Java COPIES the value of x (which is 3) and puts that COPY into y.

This is PASS-BY-VALUE. Which you can think of as PASS-BY-COPY. The value is copied, and that's what gets shoved into the new cup. You don't stuff one cup into another one.

Saying int y = x does NOT mean "put the x cup into y". It means "copy the value inside x and put that copy into y".


------------------------------------------------------------------------------

Finally the definition of pass-by-reference does use the word "aliasing" - as described in the following article from JavaDude:

http://javadude.com/articles/passbyvalue.htm

http://javadude.com/articles/passbyvalue.htm wrote:
Pass-by-value
The actual parameter (or argument expression) is fully evaluated and the resulting value is copied into a location being used to hold the formal parameter's value during method/function execution. That location is typically a chunk of memory on the runtime stack for the application (which is how Java handles it), but other languages could choose parameter storage differently.
Pass-by-reference
The formal parameter merely acts as an alias for the actual parameter. Anytime the method/function uses the formal parameter (for reading or writing), it is actually using the actual parameter.


So if JavaScript object handling is done through pass-by-reference, then it does use aliasing then right?

------------------------------------------------------------------------------

The BIG discrepancy I am seeing between the pass-by-value vs pass-by-reference paradigms is that pass-by-value does a COPY, while pass-by-reference does NOT. So if JavaScript object handling does do pass-by-reference - then from the definition it doesn't do any COPYING of its reference variable (or pointers or whatever you call them) whatsoever right? It would only be ALIASED - which I don't know whether it is considered the same equivalent or terminology to COPYING.

Again - we're talking strictly references or pointers to that object here - not the object itself...

------------------------------------------------------------------------------

Just wanted to note: Yeah - this discussion is getting very nit-picky alright - but I'm kind of loving this in-depth theoretical stuff - makes my brain actually think about the very fundamental paradigms of these languages...
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

Perry Terrance wrote:But I think we're talking about the same thing here. Note: I said two references - not objects, so there does exist two references.

You language was not clear.

The exact same thing happens in Java as in JavaScript. And the behavior of assignments has nothing at all to do with pass-by semantics. The passage you quoted was for illustrative purposes only.

Also, don't get confused about primitives versus objects.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Bear Bibeault wrote:
The exact same thing happens in Java as in JavaScript. And the behavior of assignments has nothing at all to do with pass-by semantics.


So the pass-by semantics are really only about param argument passing only - and nothing else?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

That's way it's called "pass by".
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Then what is the difference (in object handling) between JavaScript's pass-by-reference (which seems to pass an alias of the reference variable) vs Java's pass-by-value (which makes a copy of the reference variable) inside the method? This is again - going back to the question of "alias" vs "copy"...
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

There is no difference.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Then why would Paul's example logic work differently then between pass-by-value and pass-by-reference for object-reference variables?



Why would I get -
In a pass-by-value language you would see "unchanged", but in a pass-by-reference language you would see "something else".


Something must be different between an "alias" and a "copy" for this to happen.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61010
    
  65

Paul's and my examples work the same as in Java; the reference is passed "by value". Whether you think that means pass-by-value or pass-by-reference comes down to what your definition of "pass by reference" means.

Search the Java forums for past discussions on this. I'm not going to rehash it all over.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
Bear Bibeault wrote:Paul's and my examples work the same as in Java; the reference is passed "by value". Whether you think that means pass-by-value or pass-by-reference comes down to what your definition of "pass by reference" means.

Search the Java forums for past discussions on this. I'm not going to rehash it all over.


Oh finally - I figured it out - this was a big detour on my part and so thank you for clearing it up Paul and Bear - JavaScript IS AND ALWAYS IS a "pass-by-value" language, just like Java.

Therefore the following semantic holds true for this JavaScript language as does Java:

Pass-by-value
The actual parameter (or argument expression) is fully evaluated and the resulting value is copied into a location being used to hold the formal parameter's value during method/function execution. That location is typically a chunk of memory on the runtime stack for the application (which is how Java handles it), but other languages could choose parameter storage differently.


I think the confusion occurred when I was reading how JavaScript would do "pass in by value" for primitive values but "pass it in by reference" for objects.

This article here particularly confused me on the matter: http://snook.ca/archives/javascript/javascript_pass/

http://snook.ca/archives/javascript/javascript_pass/ wrote:When passing in a primitive type variable like a string or a number, the value is passed in by value. This means that any changes to that variable while in the function are completely separate from anything that happens outside the function.
Passing in an object, however, passes it in by reference.


But in the end - JavaScript is completely a "pass-by-value" language. When dealing with objects in JavaScript, the value being passed (copied) is a reference itself, but that does not mean its a "pass-by-reference" language. Again - this might be a mix-up of terminology, but I like to follow the very strict and literal definition of what constitutes a language being "pass-by-value" or "pass-by-reference" in terms of method-calling semantics.

There are some other languages I read, that are truly "pass-by-reference" languages so even primitive values in those languages are not passed directly to the method - so I am very keen on distinguishing the terminology.
Perry Terrance
Ranch Hand

Joined: Oct 02, 2009
Posts: 55
And to finish this discussion - here is your sample test Bear that I tweaked a little with comments of JavaScript's pass-by-value in action for reference types:


Running this the alert boxes will spit out 2, 1, 2 in that order.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Is JavaScript really Pass-By-Reference?