JavaScript: Get Argument Value and NAME of Passed Variable [duplicate]

What I want to do is get the NAME of a variable passed to a function and the VALUE of that variable, and only have to pass in one variable to the function. So:

var x = "anything";

function showName() {

}

showName(x);

or

showName("x");

Which will return: "x = anything".

Right now, I have to specify the variable twice:

showName("x", x);

In order to get the name and value of the variable I am passing in.

Note that I am not interested in the name of argument in the prototype of showName, but the name of the variable in the calling function. Also, the variable passed may be local, so I can't use the window object to find the variable.


Solution 1:

The short answer is that you can't.

The longer, evil answer is that you sort of can with some real nastiness. And it only works when called from another function.

there are two interesting attributes available to you that could help

arguments.callee caller

for fn to do something like this:

(function(){
  var showMe = function(s){
    alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] + 
    ' = '+ s)
  }
  x = 1
  showMe(x)
})()

What arguments.callee.caller.toString().match(..)[1] does is look for the showMe being called in the function calling it and prints it and its value.

But this is still pretty limited because it will only hit the first call of showMe(x). So if there is two calls to it, it won't work.

But, it was fun to play with these arcane things.

Solution 2:

Strategy 1:

If you can control the data structure during function invocation then you can pass a dictionary which will encode name as a key, paired with its value, notice the stealth curly braces:

var foo = "bar";
yourfunction({foo});

Which passes a javascript dictionary that looks like this:

{foo : "bar"}

When yourfunction( is executed, unpack name and value thustly:

yourfunction = function(dict) { 
    var name = Object.keys(dict)[0];
    var value = dict[name];
    console.log(name);        //prints foo
    console.log(value);       //prints bar
}

Strategy 2:

If you can maintain an as-you-go list of name-value pairs in a global scope, then reflection and introspection is always available for set and get, for example:

var my_global_stack = [];

yourfunction = function() { 

    //Chomp the stack
    var dict = my_global_stack.pop();

    //The name is the key at index 0
    var name = Object.keys(dict)[0];

    //Fetch the value by keyname:
    var value = dict[name];

    console.log(name);       //prints foo
    console.log(value);      //prints bar
}


foo = "bar";
my_global_stack.push({foo});
yourfunction();

Strategy 3:

If user-hostile input isn't an issue, you can use eval( to rediscover value given variablename, for example:

yourfunction = function(somevariable) { 
    console.log(somevariable);          //prints foo
    console.log(eval(somevariable));    //prints bar
}

foo = "bar";
yourfunction("foo");

People say eval( is evil here, because if a hostile user is able to overwrite the value of foo in memory at any point, then they can do OS Command Injection and run any command they want.
http://cwe.mitre.org/top25/#Guidance