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



Question:

This question already has an answer here:

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 do:

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 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

var x = "anything";    function showName(s) {      alert(s + " = " + eval(s));  }    showName("x");  

Not recommended, but there it is.


Solution:3

I already knew that I could pass in a object:

{a:"this is a"}  

where a is name of the variable but I really want to just pass in a variable or the name of a variable (a or "a") and let the function somehow find the name of the variable and its value.

The reason I want to do this somewhat weird thing is that I am writing a debug print routine. If I call it like this:

var x = "some string";  say(x);  

or

say("x");  

I want it to print something like:

X (string) = some string  

I can pretty reliably find the type of a variable passed, and so I know how to print it, but I really want to try to avoid the redunancy of having to call it like this:

say("x", x);  

which is what I have to do now.

What seems to almost work is OrbMan's answer. Sure, eval is evil, but I think it's OK here because it's only for a debug utility and won't be in the published code. I've made a little test routine of my own using that solution:

var x = "this is x";    function say(a) {     alert(a + " = " + eval(a));    }    say("x");  

and it works but ONLY IF X IS GLOBAL. This doesn't work:

function wrapper() {       var x = "this is x";     say("x");    }  

So, this solution is close, but since I use almost no Global variables, this isn't going to work. Darn, it is soooo close. What I think I need is "call by name" instead of "by value" or "by reference". And I need a function that will work whether it is being called from another function or not.

Since I've put in a good many hours on this myself, asking the question here was an act of desperation, I've got to conclude that there really isn't any way to do this. Shucks.

To everyone who responded, thanks for all your help.


Solution:4

You could create a hash and pass that in:

var x = {a: 1,b:2}  function showVars(y) {      for (var z in y) { alert(z + " is " + y[z]); }  }  showVars(x);  

This doesn't necessarily show the name of the variable, but it does allow for key-value pairs, which may be more to the point of what you need.


Solution:5

This is what I use for debugging. No global variables, no eval, no arguments.callee or arguments.caller:

var Helpers = (function () {      // ECMAScript 5 strict mode      'use strict';        var Module = {};        Module.debug = function () {          var i;            for (i = 0; i < arguments.length; i++) {              console.log(arguments[i] + ':', this[arguments[i]]);          }      };        Module.SomeObject = function SomeObject() {          this.someMember = 1;          this.anotherMember = 'Whatever';            Module.debug.call(this, 'someMember', 'anotherMember');            var privateMember = {              name: 'Rip Steakface',              battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!'          };            Module.debug.call(privateMember, 'name', 'battleCry');      };        return Module;  }());  

For those who are wondering why you would want to do this, it's just a way to efficiently log multiple variables along with their names.

If you want to be able to log nested members, as in Module.debug.call(obj, 'hair.fluffiness'), you can modify the function like so:

Module.debug = function () {      var i, j, props, tmp;        for (i = 0; i < arguments.length; i++) {          tmp = this;          props = arguments[i].split('.');            for (j = 0; j < props.length; j++) {              tmp = tmp[props[j]];          }            console.log(arguments[i] + ':', tmp);      }  };  

Unfortunately, I can't find any way to efficiently log multiple private variables that aren't members of an object, e.g. var roll = 3, value = 4; Module.debug.call(???);


Solution:6

Not sure you can directly get what you want from JavaScript, since the variable name is not carried around with the value it references (think of variable names as identifiers only the compiler knows about; but which get thrown away at runtime).

You can, however, do something slightly different which allows for passing around named arguments. Create an anonymous object and pass that to your function:

function showNames(o)  {      for( var ix in o )      {         alert( ix + ":" + o[ix] );      }  }    var z = { x : "Anything" }  showNames( z );  // or  showNames( { a : "ay", b : "bee", c: "see" } )  

For iterating object properties, I tend to prefer a functional-style, as in:

Array.iteri = function(o, f)  {      for(var i in o) { f(i, o[i]) }  }    function showNames(o)  {      Array.iteri( o, function(i,v)      {          alert( i + ": " + v )      });  }  showNames( { a : "ay", b : "bee", c: "see" } )  


Solution:7

The below code is about the best you can do. Unfortunately local variables in a function are properties of the hidden Call Object so they can't be accessed from Javascript like window[a] where a is a property of the window object.

x = "this is x";  var say = function(a) {      document.write(a + " = " + window[a]);  }  say("x");    var wrapper = function () {      var x = "this is x";      document.write(x + " = " + eval("x"))  }  wrapper()  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »