2

Is it possible to send a link to a global variable to a function in JavaScript? This answer says no, but I cannot believe, there is no workaround.

What I mean is something like the following. It is not working, but it shall explain what I mean:

var data_1;
var data_2;

fillValue(data_1,"First");
fillValue(data_2,"Second");

function fillValue(link2GlobalVar, value){
    link2GlobalVar = value;
}   

console.log(data_1);
console.log(data_2);

It would be great if it was possible to output in the console

First
Second

Do you know a trick to send global variables to functions and change them within them like this?

See Fiddle

Community
  • 1
  • 1
wurstbrotrest
  • 329
  • 1
  • 7
  • 17

3 Answers3

4

JavaScript doesn't have references in the same way other languages do. When you do fillValue(data_1,"First"); you are passing data_1 by value. So, you can't update data_1 because in the function all you have is a copy of the data.

If these variables are global, then you can do what the linked answer suggests and pass the variable name:

fillValue("data_1", "First");
fillValue("data_2", "Second");

function fillValue(link2GlobalVar, value){
    window[link2GlobalVar] = value;
}

UPDATE: In JavaScript, if you pass an object as a parameter, then it is actually passed by reference. You can try something like this:

var datas = {};

fillValue(datas, "data_1", ,"First");
fillValue(datas, "data_2", "Second");

function fillValue(obj, key, value){
    obj[key] = value;
}
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • 1
    @blex - it's the same answer, this is just explained better. – adeneo Jun 15 '15 at 19:37
  • @adeneo sorry I got carried away, thinking OP was already passing a string as the variable name, as in [the answer he linked](http://stackoverflow.com/questions/18178728/passing-a-global-variable-to-a-function/18178788#18178788). +1 – blex Jun 15 '15 at 19:38
  • 1
    @blex - Actually, Crayons answer seems to be wrong as it's **not** passing a string, and that answer won't work. – adeneo Jun 15 '15 at 19:41
  • @adeneo Ah, true, it's like saying `window[undefined] = value;` – blex Jun 15 '15 at 19:43
  • 1
    If we don't want to assume there is a browser, and thus, a `window` object, would this be better? http://jsfiddle.net/j90kurvy/ – blex Jun 15 '15 at 19:48
  • 1
    I'm willing to concede (and delete my answer) to the point of it being passed as a variable reference instead of a string (though really I blame OP for that, not my answer) but re: "maybe not a browser" I think y'all looking too far into it lol – CrayonViolent Jun 15 '15 at 19:50
3

Primitive values aren't passed by reference. Objects are.

If you wrap the globals in an object, you'll be able to modify its properties from a function:

var data_1 = {};
var data_2 = {};


fillValue(data_1,"First");
fillValue(data_2,"Second");

function fillValue(link2GlobalVar, value){
    link2GlobalVar.value = value;
}   

document.write(data_1.value + "<br/>" +data_2.value);

Other than that, this, should be more portable than window. (Works both in the browser and on nodejs). You can't use it from inside functions (that aren't called with new) if you're in strict mode, but you can use it in global scope to get a reference to the global scope.

"use strict";
var data_1;
var data_2;
var global = this;  //get a reference to the global object
    
fillValue("data_1","First");
fillValue("data_2","Second");

function fillValue(globalVariableName, value){
    //`this` instead of `global` would work here only if you're not in strict mode
    global[globalVariableName] = value;
}   

document.write(data_1 + "<br/>" +data_2);
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • 2
    I like this better than my own answer. It's probably closer to what the OP wants. – gen_Eric Jun 15 '15 at 19:50
  • 1
    I wouldn't actually use `this`. It doesn't work in "strict mode". From the [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#.22Securing.22_JavaScript): "in browsers it's no longer possible to reference the `window` object through `this` inside a strict mode function." – gen_Eric Jun 15 '15 at 20:05
  • 1
    Thanks for the hint with node.js! – wurstbrotrest Jun 15 '15 at 20:07
  • Thanks for the comment, @RocketHazmat. I've amended the second solution to make it work around that. Works on my chromium, firefox, and node. – Petr Skocik Jun 15 '15 at 20:17
0

this question seems a little crazy but you could pass the name of the global as string and then set with an eval:

function blah(nameAsString, val){ eval("window." + name + " = " + val);}

even crazier! :)

  • This is a potential security hole (and a huge one at that) unless you sanitize things. – Petr Skocik Jun 15 '15 at 20:05
  • Please don't actually do this. Why would you do `"window." + name` inside `eval()` over `window[name]` without `eval()`? – gen_Eric Jun 15 '15 at 20:07
  • The option using eval is actually a good option if a variable should be constructed using strings. I tried to make this example running (http://jsfiddle.net/gulli/7ft65ma5/) but I was not successful. Any ideas to fix this? – wurstbrotrest Jun 15 '15 at 20:21