-4

Let’s say I have this function:

function myFunction(x,y,z) {
   this.var1 = x*y;
   this.var2 = "someting else";
};

myFunction.prototype.whatismyname = function() {
 // return my name here.
};

var varName = new myFunction(10,99,7);

I would like to call varName.whatismyname(); and have it return the text "varName", or whatever the name of the declared variable is. That is, can I have a method that will give me the name used to declare an instance variable?

Jeremy
  • 1
  • 85
  • 340
  • 366
  • 1
    This isn’t really possible, maybe because this shouldn’t be necessary, ever. – Sebastian Simon Feb 29 '16 at 21:40
  • In the title it says “within the function”, in the question you declare it outside the function. Which is it?! – Sebastian Simon Feb 29 '16 at 21:42
  • why is the question unclear? I have a function, which once its called it write a bit of code using document.body.innerHTML,+="...." in the content I write I want to reference the name of the variable used to declare the function.... it helps simplify a complex process. so, maybe not necessary.. but very helpful to be able to do this. – Sergio Fernandez Feb 29 '16 at 21:45
  • sorry for the terrible spelling, just noticed it now. Xufos.. the variable is declare outside.. but you reference the declared name from inside. – Sergio Fernandez Feb 29 '16 at 21:48
  • @SergioFernandez When you're typing a comment, there's automatic name completion after '@'. – Barmar Feb 29 '16 at 21:49
  • yes, I know j08691.. how can I edit the title, when I write fast, sometimes, that happens... should have checked the spelling. – Sergio Fernandez Feb 29 '16 at 21:50
  • Click the [edit] link under the question. – Sebastian Simon Feb 29 '16 at 21:51
  • You can't get the name of a variable that was used to call a function. Functions are called by value, nothing about the variable is passed along. There might not even be a variable, it could be `someotherFunction().whatismyname()`. – Barmar Feb 29 '16 at 21:51
  • No, this is not possible. Variables names are not accessible from JavaScript in any way short of something insane like hooking into your own environment's debugger. – Jeremy Feb 29 '16 at 21:52
  • @Barmar... OK that sucks, it could be very useful a feature to reference the name, and if there is no variable name ... then when you try to get the name you could get maybe '()' or a empty string back ''. well, thanks for who ever fixed the title of the question. – Sergio Fernandez Feb 29 '16 at 21:55

1 Answers1

1

This isn't practically possible. Local variable names are not preserved in any semantic way in JavaScript; the language has no reflection capabilities that would let you retrieve them. It might be hypothetically possible to have a program in the right environment connect to its own debugger port to determine a local variable name, but that would extremely complicated and slow.

But as a fun exercise, here's a function which will work for the specific example you've provided. PLEASE DO NOT USE THIS FUNCTION IN REAL CODE. This code checks the name of your class (this.constructor.name), and then searches up the call stack for any parent functions containing X = new NAME, and returns the first X it finds. This approach is extremely crude and unreliable, relies on the super-deprecated .caller property, will probably hurt your application performance, won't work in strict mode, and your coworkers will give you dirty looks.

function myFunction(x,y,z) {
  this.var1 = x*y;
  this.var2 = "someting else";
};

myFunction.prototype.whatismyname = function() {
  // Get the name of this class's constructor.
  var name = this.constructor.name;

  // Start by searching in the function calling this method.
  var caller = arguments.callee.caller;  
 
  var match = null;

  // Search up the call stack until we find a match or give up.
  while (!match && caller) {
    // Get the source code of this function on the stack.
    var code = caller.toString();

    // Search the source code for X = new NAME.
    var match = new RegExp('\\W(\\w+)\\s*=\\s*new\\s+' + name).exec(code);

    // Move up the stack.
    caller = caller.caller;
  }

  // Return the first match.
  return match && match[1] || undefined;
};

function main() {
  var varName = new myFunction(10,99,7);
  other(varName);
}

function other(myObj) {
  console.log(myObj.whatismyname()); // "varName"
}

main();

It "works"! Sort-of. In this case. Don't do it.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • @ Jeremy Banks. yes it works, this is what I am looking for, but I have read, all the comments which discourage us to use this method.... I'll see if their is an alternative to arguments.callee.caller.... since this way it reduces a complex bit of code to a single line. – Sergio Fernandez Feb 29 '16 at 22:27
  • well it works for Firefox,chrome, but not IE.. under vista... have not tried it under mobile... but its a good step towards what I wanted. – Sergio Fernandez Feb 29 '16 at 22:38