最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript Reflection: obtaining a variable's name? - Stack Overflow

programmeradmin1浏览0评论

I have a several variables which are assigned to the same function. The property 'name' is "" as this function is anonymous;

There also isn't a function call involved, and as such no callee.

Is there a way in JS to obtain the variable's name, through a self-implemented reflection algorithm?

e.g.

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

Background:

for space efficiency, thousands of variable names are assigned to the same 'static' function as a lazy-loaded stumps, which get resolved to individual functions upon the first call invocation. (The variable name also contains a namespace).

Alternatives:

My alternative would be the use of objects such as {_name: myUnknownNamedVar1 , _fn: x}

Solutions to this issue would be interesting. A particular issue is discerning variables with different names ,in the script, which point to the same object.

I have a several variables which are assigned to the same function. The property 'name' is "" as this function is anonymous;

There also isn't a function call involved, and as such no callee.

Is there a way in JS to obtain the variable's name, through a self-implemented reflection algorithm?

e.g.

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

Background:

for space efficiency, thousands of variable names are assigned to the same 'static' function as a lazy-loaded stumps, which get resolved to individual functions upon the first call invocation. (The variable name also contains a namespace).

Alternatives:

My alternative would be the use of objects such as {_name: myUnknownNamedVar1 , _fn: x}

Solutions to this issue would be interesting. A particular issue is discerning variables with different names ,in the script, which point to the same object.

Share Improve this question edited Sep 23, 2012 at 19:51 Lorenz Lo Sauer asked Oct 22, 2011 at 19:09 Lorenz Lo SauerLorenz Lo Sauer 24.7k16 gold badges87 silver badges87 bronze badges 4
  • I'm not sure what you're asking. You want to find the string names of variables that point to x? – Dave Newton Commented Oct 22, 2011 at 19:19
  • fnmap.remoteNotYetMappedFunc(1,2,3,4) 1. store the parameters in a queue 2. load remote information and create an individual function and reassign it to fnmap.remoteNotYetMappedFunc – Lorenz Lo Sauer Commented Oct 22, 2011 at 19:31
  • If your question is can you get the names of variables pointing to an object the answer is no. If your scenario is different (e.g. you could iterate through a namespace and check references), then it might be possible, but I didn't understand any of your explanation. – davin Commented Oct 22, 2011 at 19:36
  • Let me know if I understand your question correctly. I posted an answer. – vol7ron Commented Oct 22, 2011 at 20:24
Add a comment  | 

5 Answers 5

Reset to default 10

It is possible to use object reflection, as such:

const getVarName = obj => Object.keys(obj)[0];
const varToGetTheNameOf = "Value!";
getVarName({ varToGetTheNameOf }) // => "varToGetTheNameOf"

No. There is not.

A simple explanation (that reinforces the point in the post) for this is simply: a variable (or property) is not a value/object. Rather, it is a "name" for a value/object. The same object can be named multiple times.

Imagine this example, and consider how it maps to "names" given to people :-)

var fred = function Fred () {}
fred.name // "Fred"

// An unknown number of nicknames can exist...
var francisco = fred
var frankyTheFiveFingers = fred
someOtherRegion.theGoodPerson = fred

// But sometimes nicknames are known; note that this is
// a locatable (e.g. "known") iterable set.
// (While properties can be iterated, variables cannot.
//  However, iterating *every* object is not feasible, hence
//  it must be a locatable set.)
fred.nicknames = ["Freddy", "FD"]

mary.nicknamesFor(fred) // who knows :-)     

Happy coding.

1. You could try parsing the script's text.

JSFiddle Example

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

var txt  = (document.currentScript && document.currentScript.textContent) ||
           (document.scripts       && document.scripts[1]
                                   && document.scripts[1].textContent);
var arr  = txt.match(/var\s*(.*)\s*=\s*x\b/);
arr[1]   = arr[1].replace(/\s+$/,"");
var vars = arr[1].split(/\s*=\s*/);

// vars: ["myUnknownNamedVar1", "myUnknownNamedVar2"]

2. You can try comparing values

JSFiddle Example

var x = function(){}
var myUnknownNamedVar1 = myUnknownNamedVar2 = x;

var vars = [];
for (var prop in window){
    if (window[prop] == x)
      vars.push(prop);
}

// vars: ["x", "myUnknownNamedVar1", "myUnknownNamedVar2"]

Note: Both methods will need refining (eg recursion, better/more match patterns). The second one only looks at global variables, whereas some variables in closures may not be exposed to the global namespace. Also, there are objects of objects.

You can use decorators to detect the name of variable that must be :

(a)- Class

(b)- Attribute of class or of instance

(c)- Method of class or of instance


The decorator provides 3 informations about the decorated :

  1. target
  2. key
  3. Descriptor

Thus:

  • the name of (a) is target.name
  • the name of (b) or (c) is key directly

     function logName(target, key) {
       console.log(!key ? target.name : key);
     }
    

example (Try Fiddle) :

  @logName
  class Person {

     @logName
     firstname="Someone";

     @logName
     fullName() {
       return this.firstname+' '+this.lastname;
     }

  }

Try Fiddle

One trick you can do is something like this:

    
let myVariable = 1;
console.log((()=>myVariable).toString().replace('()=>', '')) 

发布评论

评论列表(0)

  1. 暂无评论