12

Lets say I have an inline script tag that has a very simple code as follows

(function() {
 var test = "This is a simple test";

 function modifyTest(s) {
  s = "Modified test text";
 };

 modifyTest(test);
 console.log(test) //Will still display "This is a simple test"

 })();

However if i use test = modifyTest(test); the change is applied my question is this. Is this the only way to modify a variable in javascript inside a function, meaning i must always do

source = function(source); inorder to alter a variable inside a function,

or am i missing a scope concept that is preventing me from accomplishing this?

Mouseroot
  • 1,034
  • 2
  • 9
  • 13
  • 8
    JavaScript uses pass by value, not pass by reference. Assigning to a variable **never** changes the value of another variable. If you want to change the value of a specific variable, you have to explicitly assign to that variable. – Felix Kling Feb 24 '14 at 03:30
  • 2
    @Felix Kling: "uses pass by value, not pass by reference" --- that's not entirely true. It passes references by values (for reference types) – zerkms Feb 24 '14 at 03:31
  • 3
    @zerkms: I'm pretty sure it is. If you have objects in mind, the values are the references to the objects. *pass-by-reference* is a very well defined term. – Felix Kling Feb 24 '14 at 03:31
  • 1
    @Felix Kling: `var a = {}; console.log(a);` <-- here a reference to `a` is passed – zerkms Feb 24 '14 at 03:32
  • 1
    @zerkms: Nope. https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_reference – Felix Kling Feb 24 '14 at 03:33
  • 1
    @Felix Kling: it has nothing to do with function calls specifically `var a = {}; var b = a;` – zerkms Feb 24 '14 at 03:34
  • JavaScript does both - pass by value and pass by reference. It depends how you use it. – Anmol Saraf Feb 24 '14 at 03:34
  • 3
    @zerkms: No. pass or assign by reference means that the variable gets a reference to another variable, not to its value. JavaScript is always pass by value, and in case of objects, that value is a reference *to the object*, not to the variable. What you are referring to is called call by sharing in the Wikipedia article: https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing, but essentially it's pass by value. – Felix Kling Feb 24 '14 at 03:36
  • 1
    Felix is correct; if you have 3 vars set to the same object and you set one to null, the other two are still the same object. – dandavis Feb 24 '14 at 03:37
  • 2
    Duh, both on same point - " It passes references by values" | "essentially it's pass by value" – loxxy Feb 24 '14 at 03:38
  • @loxxy: Ha, I missed that part :D Still, it's pass by value, not pass by reference, because that means something different. – Felix Kling Feb 24 '14 at 03:39
  • @Felix Kling: Yep, now I see the original point, apologies :-) – zerkms Feb 24 '14 at 03:40
  • @dandavis what if one changes the value of a property of that object. var a = {x:1, y:2}; var b = a; var c = a; b.x = 10; console.log(c.x); – Anmol Saraf Feb 24 '14 at 03:40
  • @zerkms: No worries :) At this level it's easy misunderstand each other I guess ;) I misunderstood you as well... sorry for that! – Felix Kling Feb 24 '14 at 03:41
  • @AnmolSaraf: You are mutating the object itself, you don't change the value of the variable. – Felix Kling Feb 24 '14 at 03:41
  • Javascript ALWAYS passes variables by value. It's just the same thing you get in Java: "call-by-reference effects". As the value of Object-types is a memory-address (some somewhat a reference), it looks like objects are passed by reference. – Johannes H. Feb 24 '14 at 03:42
  • my comment said they are the same object... and for the string in the OP, it's pretty simple... – dandavis Feb 24 '14 at 03:42
  • Well I was trying to create malloc/free implementation in javascript and noticed that functions where not modifying the passed in values, so I decided to ask the guru's very insightful stuff, javascript gets more interesting the more i use it. I think im going to use Ethan's example and wrap my 'memory' in objects so that they can be 'passed by reference' in-order to accomplish what im trying to do. – Mouseroot Feb 24 '14 at 03:52
  • There is no need for `free` in Javascript BTW. If some variable isn't inside the scope of any function that has valid references pointing to it, it should get freed by the engine automatically. – Johannes H. Feb 24 '14 at 04:12
  • well I know that the GC will automatically 'free' variables that no longer point to anything, So essentially that's all free would do is tell the GC that your done with it (by setting it to null, so that its no longer holding a reference), this is just a toy project inspired by lljs. – Mouseroot Feb 24 '14 at 04:32

2 Answers2

20

The modifyTest function is essentially creating a local, function-level variable called s; that variable only exists within the scope of the function, so modifying it will not effect external scope.

If you want to modify the external scope, you would not use an argument:

var test = "This is a simple test";
function modifyTest(){
    test = "modified test text";
}
console.log(test);   // This is a simple test
modifyTest();
console.log(test);   // Modified test text

Note that you can modify an object passed by reference, so you can modify something's properties:

var o = { test: 'This is a simple test' };
function modifyTest(x){
    x.test = 'modified test text';
}
modifyTest(o);
console.log(o.test);   // modified test text

You could even pass in the name of the property you wish to modify:

var o = { test: 'This is a simple test' };
function modifyTest(x, name){
    x[name] = 'modified test text';
}
modifyTest(o, 'test');
console.log(o.test);    // modified test text
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • My problem is that I need the variable to be passed in, because really it doesn't make sense to want to modify a 'static' variable it should be dynamic. – Mouseroot Feb 24 '14 at 03:38
  • 1
    I don't think you're using the words "static" and "dynamic" in the correct context. What you mean is that you want to be able to modify any variable by name. If that's your goal, you should look at my second example, using an object and modifying one of its parameters. There is no way to do what you're asking, and that's as it should be. – Ethan Brown Feb 24 '14 at 03:41
  • However the object example is interesting perhaps I could change my code to use an object so that I could accomplish this. – Mouseroot Feb 24 '14 at 03:41
  • You could look at macros in JavaScript via something like Sweet.js (http://sweetjs.org/), but I might try re-thinking your problem first. – Ethan Brown Feb 24 '14 at 03:41
  • ANother way to trick variable visibility/scope is to return functions that have references to local variables. It's a common way to get private variables inside Javascript. – Johannes H. Feb 24 '14 at 03:44
  • by dynamic I mean the user should be able to create the variable that is passed in and not just a global variable that exists. within the code at some point (if that makes sense) – Mouseroot Feb 24 '14 at 03:50
  • It makes sense (I knew what you meant), but "dynamic" and "static" have very specific meanings in terms of computer languages. And I'm a stickler for words ;) – Ethan Brown Feb 24 '14 at 03:54
5

You're talking about calling a function "by reference". JavaScript (like most other functional languages) doesn't support that, as, changing a variable that is outside the current scope is a side-effect and those contradict functional programming paradigms.

You can always change variables inside the current scope though. So any function defined within another function can change any local variable of the outer one.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Johannes H.
  • 5,875
  • 1
  • 20
  • 40