Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts

    can you enumerate local variables?

    I was wondering if it is possible to find the names of all the local variables.

    Like

    Code:
    function func() {
      var x = 5;
      var y = 8;
    
      // some code
    
      for (key in func.local) {
        alert(key + "=" + func.local['key']);
      }
    }
    and you'd get two alerts
    x=5 and y=8

    Is anything like that or similar possible? I know you can get the arguments with the argument[] object.

    Thanks,
    david_kw

  • #2
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    Nope. The variable object is not available from script in any way, except for the global object or objects used in with statements.

    There have been some JavaScript engines that exposed all locals as named properties of the function object (only while the function was running however), but nothing you can rely on.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards

  • #3
    Senior Coder chump2877's Avatar
    Join Date
    Dec 2004
    Location
    the U.S. of freakin' A.
    Posts
    2,855
    Thanks
    22
    Thanked 157 Times in 148 Posts
    The closest I can think of to acheive something like that is this:

    Code:
    <script type="text/javascript">
    
    function whatever()
    {
      var obj = new Object;
    
      obj.x = 5;
      obj.y = 8;
    
      for (var prop in obj)
      {
        alert(prop + "=" + obj[prop]);
      }
    }
    
    </script>
    
    <input type="button" value="click me" onclick="whatever();" />
    ...make the object a local "variable" and iterate through the property/value pairs in the object...
    Regards, R.J.

    ---------------------------------------------------------

    Help spread the word! Like my YouTube-to-Mp3 Conversion Script on Facebook !! :-)
    [Related videos and tutorials are also available at my YouTube channel and on Dailymotion]
    Get free updates about new software version releases, features, and bug fixes!
    ♪♪ …Need Web Hosting For My YouTube-To-Mp3 Conversion Software? Check Here !!… ♪♪

  • #4
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hmm, bummer. Ok thanks a lot. Saves me a lot of time searching even more for something that doesn't exist.

    david_kw

  • #5
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Well I came up with a hack sort of way to do it. In case you are wondering why I wanted this functionality, I am trying to put together a better closure breakpoint (I hate the IE debugger, thank god for FireBug) like

    http://trimpath.com/project/wiki/TrimBreakpoint

    Basically, I found that arguments.callee is the function, so I do a toString() on it then parse it for variable names. I have no doubt some might slip by my parsing depending on how it is declared, but it seems to get most of them (at least the way I declare them).

    Here's the code to parse the function in case you are interested

    Code:
    function getLocals(args) {
      var ret = [];
      var reArg = /\(?\s*(\w+)\s*(,|\))/g;
      var reHasVar = /\Wvar\W/;
      var reGetVar = /(var|,)\s*(\w+)/g;
      var a = args.callee.toString().split("\n");
      var lookForArgs = true;
      var reResult;
    
      ret.push(a[0]); // save the function name for later use
      
      for (var i = 0; i < a.length; i++) {
        if (lookForArgs) {
          while ((reResult = reArg.exec(a[i])) != null) {
            ret.push(reResult[1]);
          }
          if (/\{/.test(a[i])) {
            lookForArgs = false;
          }
        }
        if (!lookForArgs) {
          if (reHasVar.test(a[i])) {
            while ((reResult = reGetVar.exec(a[i])) != null) {
              ret.push(reResult[2]);
            }
          }
        }
      }
    
      return(ret);
    }
    It's called like
    getLocals(arguments);
    and returns an array of arguments and local variable names which I can iterate through using eval to get the values.

    Thanks again. I imagine without your help I'd still be searching the web for some way it is exposed by the browser.

    david_kw

  • #6
    Senior Coder
    Join Date
    Nov 2006
    Posts
    1,000
    Thanks
    0
    Thanked 0 Times in 0 Posts
    For anyone interested. I fixed a few bugs in my getLocals function and made it more flexible when searching for variables. Here is the code plus a working example.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html>
      <head>
        <title>Enumerate Local Variables</title>
        <script type="text/javascript">
        /* <![CDATA[ */
          function indexInLiteral(str, index) {
            var inStrLiteral = 0;
            var inObjLiteral = 0;
            var inArrayLiteral = 0;
    
            for (var i = 0; i < str.length; i++) {
              if (inStrLiteral) {
                if (str.charAt(i) == "'" || str.charAt(i) == '"') {
                  inObjLiteral--;
                }
              } else {
                if (str.charAt(i) == "'" || str.charAt(i) == '"') {
                  inObjLiteral++;
                }
              }
              if (!inStrLiteral) {
                if (inObjLiteral) {
                  if (i == index) {
                    return (true);
                  }
                  if (str.charAt(i) == "}") {
                    inObjLiteral--;
                  }
                } else {
                  if (str.charAt(i) == "{") {
                    inObjLiteral++;
                  }
                }
                if (inArrayLiteral) {
                  if (i == index) {
                    return (true);
                  }
                  if (str.charAt(i) == "]") {
                    inArrayLiteral--;
                  }
                } else {
                  if (str.charAt(i) == "[") {
                    inArrayLiteral++;
                  }
                }
              }
            }
    
            return (false);
          }
    
          function getLocals(args) {
            var ret = [];
            var reArg = /\(?\s*(\w+)\s*(,|\))/g;
            var reEndArg = /\{/;
            var reHasVar = /(\W|^)var\W/;
            var reGetVar = /(var|,)\s*(\w+)/g;
            var a = args.callee.toString().split("\n");
            var lookForArgs = true;
            var reResult;
    
            ret.push(a[0]); // save the function name for later use
            
            for (var i = 0; i < a.length; i++) {
              if (lookForArgs) {
                reArg.lastIndex = 0;
                while ((reResult = reArg.exec(a[i])) != null) {
                  ret.push(reResult[1]);
                }
                reEndArg.lastIndex = 0;
                if (reEndArg.test(a[i])) {
                  lookForArgs = false;
                }
              }
              if (!lookForArgs) {
                reHasVar.lastIndex = 0;
                if (reHasVar.test(a[i])) {
                  reGetVar.lastIndex = 0;
                  while ((reResult = reGetVar.exec(a[i])) != null) {
                    if (!indexInLiteral(a[i], reResult.index)) { 
                      ret.push(reResult[2]);
                    }
                  }
                }
              }
            }
    
            return (ret);
          }
    
          var array_of_locals;
          var str, e;
          function doIt(s) { 
            var adiv = document.getElementById("adiv");
            var x = 5, y = 9;
            var re = /^test$/;
    
            array_of_locals = getLocals(arguments);
    
            str = "Variables for ";
            for (var i = 0; i < array_of_locals.length; i++) {
              if (i == 0) {
                str += array_of_locals[i] + "<br/>";
              } else {
                str += "&nbsp;&nbsp;" + array_of_locals[i] + " = " + eval(array_of_locals[i]) + "<br/>";
              }
            }
    
            adiv.innerHTML = str;
          }
        /* ]]> */
        </script>
      </head>
      <body>
        <div>
          <button onclick="doIt('This is junque...');">Do it</button>
          <br />
          <div id="adiv"> </div>
        </div>
      </body>
    </html>
    david_kw


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •