Search code examples
javascriptvariablesgetscope

JavaScript Reflection: obtaining a variable's name?


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.


Solution

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