Getting All Variables In Scope

前端 未结 10 2143
小蘑菇
小蘑菇 2020-11-22 09:10

Is there a way to get all variables that are currently in scope in javascript?

相关标签:
10条回答
  • 2020-11-22 09:43

    As everyone noticed: you can't. But you can create a obj and assign every var you declare to that obj. That way you can easily check out your vars:

    var v = {}; //put everything here
    
    var f = function(a, b){//do something
    }; v.f = f; //make's easy to debug
    var a = [1,2,3];
    v.a = a;
    var x = 'x';
    v.x = x;  //so on...
    
    console.log(v); //it's all there
    
    0 讨论(0)
  • 2020-11-22 09:46

    I made a fiddle implementing (essentially) above ideas outlined by iman. Here is how it looks when you mouse over the second ipsum in return ipsum*ipsum - ...

    The variables which are in scope are highlighted where they are declared (with different colors for different scopes). The lorem with red border is a shadowed variable (not in scope, but be in scope if the other lorem further down the tree wouldn't be there.)

    I'm using esprima library to parse the JavaScript, and estraverse, escodegen, escope (utility libraries on top of esprima.) The 'heavy lifting' is done all by those libraries (the most complex being esprima itself, of course.)

    How it works

    ast = esprima.parse(sourceString, {range: true, sourceType: 'script'});
    

    makes the abstract syntax tree. Then,

    analysis = escope.analyze(ast);
    

    generates a complex data structure encapsulating information about all the scopes in the program. The rest is gathering together the information encoded in that analysis object (and the abstract syntax tree itself), and making an interactive coloring scheme out of it.

    So the correct answer is actually not "no", but "yes, but". The "but" being a big one: you basically have to rewrite significant parts of the chrome browser (and it's devtools) in JavaScript. JavaScript is a Turing complete language, so of course that is possible, in principle. What is impossible is doing the whole thing without using the entirety of your source code (as a string) and then doing highly complex stuff with that.

    0 讨论(0)
  • 2020-11-22 09:48

    No. "In scope" variables are determined by the "scope chain", which is not accessible programmatically.

    For detail (quite a lot of it), check out the ECMAScript (JavaScript) specification. Here's a link to the official page where you can download the canonical spec (a PDF), and here's one to the official, linkable HTML version.

    Update based on your comment to Camsoft

    The variables in scope for your event function are determined by where you define your event function, not how they call it. But, you may find useful information about what's available to your function via this and arguments by doing something along the lines of what KennyTM pointed out (for (var propName in ____)) since that will tell you what's available on various objects provided to you (this and arguments; if you're not sure what arguments they give you, you can find out via the arguments variable that's implicitly defined for every function).

    So in addition to whatever's in-scope because of where you define your function, you can find out what else is available by other means by doing:

    var n, arg, name;
    alert("typeof this = " + typeof this);
    for (name in this) {
        alert("this[" + name + "]=" + this[name]);
    }
    for (n = 0; n < arguments.length; ++n) {
        arg = arguments[n];
        alert("typeof arguments[" + n + "] = " + typeof arg);
        for (name in arg) {
            alert("arguments[" + n + "][" + name + "]=" + arg[name]);
        }
    }
    

    (You can expand on that to get more useful information.)

    Instead of that, though, I'd probably use a debugger like Chrome's dev tools (even if you don't normally use Chrome for development) or Firebug (even if you don't normally use Firefox for development), or Dragonfly on Opera, or "F12 Developer Tools" on IE. And read through whatever JavaScript files they provide you. And beat them over the head for proper docs. :-)

    0 讨论(0)
  • 2020-11-22 09:50

    In ECMAScript 6 it's more or less possible by wrapping the code inside a with statement with a proxy object. Note it requires non-strict mode and it's bad practice.

    function storeVars(target) {
      return new Proxy(target, {
        has(target, prop) { return true; },
        get(target, prop) { return (prop in target ? target : window)[prop]; }
      });
    }
    var vars = {}; // Outer variable, not stored.
    with(storeVars(vars)) {
      var a = 1;   // Stored in vars
      var b = 2;   // Stored in vars
      (function() {
        var c = 3; // Inner variable, not stored.
      })();
    }
    console.log(vars);

    The proxy claims to own all identifiers referenced inside with, so variable assignments are stored in the target. For lookups, the proxy retrieves the value from the proxy target or the global object (not the parent scope). let and const variables are not included.

    Inspired by this answer by Bergi.

    0 讨论(0)
  • 2020-11-22 09:51

    Yes and no. "No" in almost every situation. "Yes," but only in a limited manner, if you want to check the global scope. Take the following example:

    var a = 1, b = 2, c = 3;
    
    for ( var i in window ) {
        console.log(i, typeof window[i], window[i]);
    }
    

    Which outputs, amongst 150+ other things, the following:

    getInterface function getInterface()
    i string i // <- there it is!
    c number 3
    b number 2
    a number 1 // <- and another
    _firebug object Object firebug=1.4.5 element=div#_firebugConsole
    "Firebug command line does not support '$0'"
    "Firebug command line does not support '$1'"
    _FirebugCommandLine object Object
    hasDuplicate boolean false
    

    So it is possible to list some variables in the current scope, but it is not reliable, succinct, efficient, or easily accessible.

    A better question is why do you want to know what variables are in scope?

    0 讨论(0)
  • 2020-11-22 09:53

    The Simplest Way to Get Access to Vars in a Particular Scope

    1. Open Developer Tools > Resources (in Chrome)
    2. Open file with a function that has access to that scope (tip cmd/ctrl+p to find file)
    3. Set breakpoint inside that function and run your code
    4. When it stops at your breakpoint, you can access the scope var through console (or scope var window)

    Note: You want to do this against un-minified js.

    The Simplest Way to Show All Non-Private Vars

    1. Open Console (in Chrome)
    2. Type: this.window
    3. Hit Enter

    Now you will see an object tree you can expand with all declared objects.

    0 讨论(0)
提交回复
热议问题