2

Is there an equivalent in JavaScript for PHP's reference passing of variables?

[PHP]:

function addToEnd(&$theRefVar,$str)
{
    $theRefVar.=$str;
}
$myVar="Hello";
addToEnd($myVar," World!");
print $myVar;//Outputs: Hello World!

How would the same code look in JavaScript if possible?

Thank you!

Francisc
  • 77,430
  • 63
  • 180
  • 276
  • Related: http://stackoverflow.com/questions/518000/is-javascript-is-a-pass-by-reference-or-pass-by-value-language – HoLyVieR Oct 07 '10 at 03:10

4 Answers4

4

Objects are passed as references.

   function addToEnd(obj,$str)
   {
      obj.setting += $str;
   }

   var foo = {setting:"Hello"};
   addToEnd(foo , " World!");

   console.log(foo.setting);                    // Outputs: Hello World!

Edit:

  • As posted in comments below, CMS made mention of a great article.
  • It should be mentioned that there is no true way to pass anything by reference in JavaScript. The first line has been changed from "by reference" to "as reference". This workaround is merely as close as you're going to get (even globals act funny sometimes).
  • As CMS, HoLyVieR, and Matthew point out, the distinction should be made that foo is a reference to an object and that reference is passed by value to the function.

The following is included as another way to work on the object's property, to make your function definition more robust.

   function addToEnd(obj,prop,$str)
   {
      obj[prop] += $str;
   }

   var foo = {setting:"Hello"};
   addToEnd(foo , 'setting' , " World!");

   console.log(foo.setting);                    // Outputs: Hello World!
Community
  • 1
  • 1
vol7ron
  • 40,809
  • 21
  • 119
  • 172
  • 3
    No they're not. If they were, that would already work. You pass the value of the reference, which is different. This is also called [call-by-sharing](http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing). – Matthew Flaschen Oct 06 '10 at 23:45
  • Matthew Flaschen, yes they are. See above. It's as close to by reference as you're going to get. – vol7ron Oct 06 '10 at 23:47
  • 8
    Well, this isn't totally wrong, *primitive values* are "passed by value", with objects I would say, the *references* are passed by value also. An excellent article: [ECMA-262-3 in detail. Chapter 8. Evaluation strategy](http://dmitrysoshnikov.com/ecmascript/chapter-8-evaluation-strategy/) – Christian C. Salvadó Oct 06 '10 at 23:48
  • 2
    "references are passed by value" is correct. "passed by reference" is not. It doesn't matter whether you think it's "close". It's not pass by reference. – Matthew Flaschen Oct 06 '10 at 23:51
  • @CMS: that is an excellent article - one that should be read by many :) – vol7ron Oct 06 '10 at 23:51
  • @Matthew To this day I hear people saying in Java (not JS) objects are passed by reference, and primitives are passed by value. – NullUserException Oct 06 '10 at 23:52
  • 1
    @Matthew Flaschen: are you going to argue what he meant by " **in** JavaScript " too? – vol7ron Oct 06 '10 at 23:52
  • @Null, and to this day they are wrong. If they were right, `void foo(String s){s = "foo";} void bar(){String myS = "bar"; foo(myS); System.out.println(myS)}` would print "foo" when you called `bar`. – Matthew Flaschen Oct 06 '10 at 23:54
  • 2
    Object passed by reference is a totally other thing, C# has that and you can do "obj = new Object();" (inside the function) and that would change the value of obj (outside of the function too). In Javascript that just won't work. – HoLyVieR Oct 06 '10 at 23:58
  • @HoLyVieR: I think that would be the expected behavior of a true reference, but that's not what would actually happen. – vol7ron Oct 07 '10 at 00:04
  • @Null, I believe @HoLy is saying C# has the *option* of that, [`ref`](http://msdn.microsoft.com/en-us/library/14akc2c7.aspx) and `out` parameters. – Matthew Flaschen Oct 07 '10 at 00:08
  • 1
    @vol7ron: I know it sounds like folks are just being pedantic here, but the difference is as critical as it is subtle: while you can adjust your code to use object references in some situations, there are common patterns that are just not possible without true pass-by-reference - so the distinction is important. – Shog9 Oct 07 '10 at 01:05
  • @Shog9: I totally agree. Also, these comments are meant to be included with the answer. Still, when it comes to terms and neophytes, sometimes you have to infer what is being asked, not take it for the literal definition. Otherwise, as I stated above, you would be arguing about the definition of "in", which could be the inner-making of the JavaScript interpreter, or possibly the literal 3D spacial attributes of JavaScript itself. I'm not being difficult, just saying you can take what you want from the question... – vol7ron Oct 07 '10 at 01:18
  • ...still the point is made: there is no equivalent, but if one wanted to mimic something like passing by ref, you would wrap the variable in an object; which, given the question asked and the user's points, I inferred that to be what is actually sought. – vol7ron Oct 07 '10 at 01:18
  • 1
    @vol7ron: I'm fine with all of that - but to avoid confusion (because this *is* something JS neophytes get hung up on) I'd like it if you changed the first sentence in your answer (to something like, "Objects are passed *as* references"). FWIW: it's usually considered good practice here to edit key parts of comments into the answers, as comments tend to get overlooked (and, sometimes, deleted). – Shog9 Oct 07 '10 at 03:04
  • Again, I agree. Confusing answers, or answers that use a loose definition of a term vs the proper terminology, like the one I have listed, should be clarified. I believe CMS, Matthew, and Holyvier did well in making that distinction. Answer updated. – vol7ron Oct 07 '10 at 14:41
2

In Javascript there is no passing variable by reference like in PHP. There is a possible workaround to do something similar.

function addToEnd(obj, str)
{
    obj.value += str;
}

myVar={value:"Hello"};

addToEnd(myVar, " World");   
alert(myVar.value); //Outputs: Hello World!

In this example, what happens is that you pass an object to the function and inside of it, you are modifying the object (not the variable, the variable is still pointing to the same object). This is why this is not passing variable by reference has vol7ron incorrectly stated.

HoLyVieR
  • 10,985
  • 5
  • 42
  • 67
1

The other answers/comments describe the situation well enough, but I thought I'd offer and alternative if you need that style of functionality, by using a callback.

var someText = "asd";
addToEnd(someText, "fgh", function(val) { someText = val; });

and

function addToEnd(original, str, setValue)
{
    setValue(original += str);
}

but a better solution would be

var someText = "asd";
someText = addToEnd(someText, "fgh");

and

function addToEnd(original, str)
{
    return original += str;
}
Luke Schafer
  • 9,209
  • 2
  • 28
  • 29
  • you don't need `setValue` argument in the last function definition. – vol7ron Oct 07 '10 at 14:49
  • we've all been there :) This was one of the times it was confusing to me at first, mainly because it was present in the first example. Much better now that you edited it. – vol7ron Oct 08 '10 at 04:53
0

try this:

// function
function func(param,callback){
    if(param){
     if(typeof callback=='function') {
         callback.call(this,param);
     }
     return true;
    }
    return false;
}
// calling function
var variable=0;
returnValue=func(10,function(reference){variable=reference});
alert(returnValue+'/'+variable);
Rahen Rangan
  • 715
  • 5
  • 8