2

I know using eval is not at all recommended and I have read this link too. Set Variable inside Eval (JavaScript)

However, this is what I want to do. Lets say we have some code in a textbox. So I have to take that text, and then find out all the global variables, functions and objects in that code. My idea was to wrap the code in a namespace, eval it and then iterate through the properties of the namespace to get the results. However, even though the eval runs successfully, I can't access the variable defined there. Is there a better solution or some other way to get this working.

http://jsfiddle.net/DbrEF/2/ - This is the Fiddle here.

The "var code" could actually be arbitrary code. I know its unsafe to do it but I need it for a different context. Thanks

1
  • close voter - how is this too localized? Commented Mar 23, 2012 at 3:08

4 Answers 4

5

In 2015, creating a Function object is your best bet here, rather than using eval:

new Function('arg1', 'arg2', 'return arg1 + arg2')(3,4) // returns 7
Sign up to request clarification or add additional context in comments.

Comments

0

You might have better luck using a Javascript parser, like the one used by JSHint/JSLint

1 Comment

aah that's something I was trying to avoid on this.
0

here's a demo on safely using eval using "use strict"

window.onload = function(){
    'use strict'; 
    //use strict forces to run code in "strict mode" 
    //use strict prevents eval from 
    //contaminating the immediate scope

    //let's test with "foo"
    var foo = 'lol';

    //now code has "foo" but using "use strict" 
    //makes code in eval stay in eval
    //note that at the last of the code, foo is "returned"
    var code = 'var foo = {name: "Spock",greeting: function() {return "Hello " + foo.name;}}; foo';

    //store eval'ed code in evalO
    var evalstore = eval(code);

    console.log(evalstore); //code in eval stays in here, which is "inner foo"
    console.log(foo);       //"outer foo" is unharmed and daisy fresh
}​;

so whatever code you have, contain it in a function which will serve as your namespace. then have that function returned to the outside world stored as a variable. this demo shows how it can be constructed, however, works only if code is in object literal notation.

window.onload = function() {
    'use strict';

    var ns = 'lol';

    //code must be an object literal
    var code = '{name: "Spock",greeting: function(){return "Hello " + foo.name;}}';

    //store in a constructor to be returned
    var constructorString = 'var ns = function(){return ' + code + '}; ns'; 

    var evalNs = eval(constructorString);     //type function/constructor
    var evalObj = new evalNs()                //object instance

    console.log(evalNs);  //constructor
    console.log(evalObj); //the namespaced object
    console.log(ns);      //outer "ns" preserved
};​

3 Comments

That does seem to work. However, what happens when the code is something like this function Dog() { this.greet = function() { return 'Hello world'; } this.dontgreet = function() { return 'hello world'; } } Also how would it handle multiline code ? I am unable to use your example with what I pasted above. Any ideas ? Somehow this comment screwed up the code formatting above but its multiline.
updated my code. it's proof of concept, but having arbitrary code is really risky
I agree. arbitrary code is risky. However, the purpose is kind of a small ide kind of thing where we can do introspection on the objects. I see how you are implementing this but instead of your example if we take the function Dog() example I get the following error - 'missing : after property id' when running the eval. - pastebin.com/s6r5wjdc (This is the constructorString from my example). jsfiddle.net/DbrEF/7
0

Probably not what exactly OP was looking for but another option is to use outside variables to store values generated inside eval, as in:

var value;
var code = 'var foo = 42';
code = code.replace('var foo', 'value');
eval(code);
value // returns 42;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.