superluminary
superluminary

Reputation: 49132

Is there a way in JavaScript to get a list of all the local variables currently defined?

Say I have a function:

function() {
  var a = 12;
  var b = 15;
  var c = list_of_all_local_variables
}

Is there a way in JavaScript to get a list of all the variables in the current scope, so list_of_all_local_variables would contain something like {a:12, b:13}, or even just ['a','b']

Thanks!

Upvotes: 5

Views: 3666

Answers (2)

Paul Grime
Paul Grime

Reputation: 15104

A very quick stab at an AST solution.

(This is my first play with Esprima, so be gentle! I'm absolutely sure this can be improved)

<style>
pre {
    font-size: 8pt;
    font-family: Lucida Console, monospace;
}
</style>

<pre id="ast"></pre>

<script src="esprima.js"></script>

<script>
function getvars(fnStr) {
    function _getvars(body) {
        if (!body) {
            return;
        }
        if (body.length) {
            for (var i = 0; i < body.length; i++) {
                _getvars(body[i]);
            }
        } else if ("VariableDeclaration" === body.type) {
            for (var i = 0; i < body.declarations.length; i++) {
                vars.push(body.declarations[i].id.name);
            }
        } else if (body.body) {
            _getvars(body.body);
        }
    }
    var vars = [];
    var syntax = esprima.parse(fnStr);
    _getvars(syntax.body);
    document.getElementById("ast").innerHTML = JSON.stringify(syntax, null, 4);
    return vars;
}

function myfn() {
    var a = 1, b = 2, ob = { name: "ob" };
    for (var i = 0; i < 10; i++) {
        var s = "" + i;
    }
    getvars(myfn.toString()).forEach(function(___var) {
        var ___ob = eval(___var);
        console.log(___var, (typeof ___ob), eval(___ob));
    });
}

myfn();
</script>

Will print to the console:

a number 1 local-vars-in-function.html:44
b number 2 local-vars-in-function.html:44
ob object Object {name: "ob"} local-vars-in-function.html:44
s string 9 local-vars-in-function.html:44

If you only want the var names, and not the values, then you wouldn't need the inline reporting.

Upvotes: 4

Sasidharan
Sasidharan

Reputation: 3740

Reference

function getLocalVarNames (code)
{
    //Find variables declared as var, i.e. local variables in the given code
    var regex =/\bvar\b\s*(?:\s*(\w+)\s*(?:=[^,;]+)?)(?:\s*,\s*(\w+)\s*(?:=[^,;]+)?)*\s*;/g;
    var matches, result = [];
    while (matches = regex.exec(code))
    {
        for (var i = 1; i < matches.length; i++) {
            if (matches[i] != undefined) {
                //filter framework specific variables here
                if (matches[i] != "__ctx")
                    result.push(matches[i]);
            }
        }
    }
    return result;
}

Upvotes: 0

Related Questions