Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 02-03-2007, 09:28 PM   PM User | #1
david_kw
Senior Coder

 
Join Date: Nov 2006
Posts: 1,000
Thanks: 0
Thanked 0 Times in 0 Posts
david_kw will become famous soon enough
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
david_kw is offline   Reply With Quote
Old 02-03-2007, 10:16 PM   PM User | #2
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
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
liorean is offline   Reply With Quote
Old 02-03-2007, 10:33 PM   PM User | #3
chump2877
Senior Coder

 
chump2877's Avatar
 
Join Date: Dec 2004
Location: the U.S. of freakin' A.
Posts: 2,530
Thanks: 15
Thanked 128 Times in 121 Posts
chump2877 is on a distinguished road
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 Web Conversion Software on Facebook !! :)
chump2877 is offline   Reply With Quote
Old 02-03-2007, 11:01 PM   PM User | #4
david_kw
Senior Coder

 
Join Date: Nov 2006
Posts: 1,000
Thanks: 0
Thanked 0 Times in 0 Posts
david_kw will become famous soon enough
Hmm, bummer. Ok thanks a lot. Saves me a lot of time searching even more for something that doesn't exist.

david_kw
david_kw is offline   Reply With Quote
Old 02-04-2007, 06:58 AM   PM User | #5
david_kw
Senior Coder

 
Join Date: Nov 2006
Posts: 1,000
Thanks: 0
Thanked 0 Times in 0 Posts
david_kw will become famous soon enough
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
david_kw is offline   Reply With Quote
Old 03-14-2007, 08:02 PM   PM User | #6
david_kw
Senior Coder

 
Join Date: Nov 2006
Posts: 1,000
Thanks: 0
Thanked 0 Times in 0 Posts
david_kw will become famous soon enough
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
david_kw is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:24 PM.


Advertisement
Log in to turn off these ads.