0

I have some code return from server like "var myVar = 314;", I would like to create a context object like so var context = {}; and then eval the script "var myVar = 314;" into properties of context, how could I achieve this ?

I have tried the below code, but without success:

var context = {};
eval.call(context, "var myVar = 314;");

EDIT May be I wasn't clear enough in the first place, the result I expected is: after eval(), I got the properties in the context object, the aim is to avoid global scope population.

For example,

var context = {};
eval.call(context, "var myVar = 314;");

I would expect the result as context.myVar = 314.

Ryan
  • 800
  • 1
  • 13
  • 27
  • 1
    Try `context["myVar"] = 314;`? – Aadit M Shah Jul 04 '15 at 14:54
  • 1
    Variables don't go into objects. Not sure what you're actually asking. What do you want to end up with? –  Jul 04 '15 at 14:55
  • possible duplicate of [calling eval() in particular context](http://stackoverflow.com/questions/8403108/calling-eval-in-particular-context) – Kirill Slatin Jul 04 '15 at 14:56
  • 1
    Even if you use an abstraction to achieve the `this`, you're `var`ing so the value won't be set on the `this` object, just in the closure you called `eval` under. – Paul S. Jul 04 '15 at 15:14
  • @KirillSlatin No, calling eval() in particular context [link](http://stackoverflow.com/questions/8403108/calling-eval-in-particular-context) is another issue. – Ryan Jul 05 '15 at 09:37
  • @Ryan Well, the formulation of the question clearly reads so. As long as you go creating `var`s you work in `context` which can be global or local. And it's not `this` of a function. And you can't substitute context in `eval` so that a generic script would settle all its declared variables in an object you provide – Kirill Slatin Jul 05 '15 at 11:34
  • 1
    I believe [this extensible Scope class](http://stackoverflow.com/questions/9781285/specify-scope-for-eval-in-javascript/40503510#40503510) is close to what you are looking for. It lets you add private vars and use its eval method to evaluate code that uses them. It also keeps track of the var names you have added. – Bill Burdick Nov 09 '16 at 10:42
  • I believe this answer is better – Ryan Nov 19 '16 at 10:11

1 Answers1

0

Are you able to change the format of the script you get from your server? If so, follow the advice in Aadit's comment and have your server send:

context["myVar"] = 314;

or:

context.myVar = 314;

If you can't change the format, is the script literally as simple as var myVar = 314;?

If it is, try rethinking the approach. Instead of trying to eval() the script in some particular context, parse the script into a form you can work with. For example:

var script = 'var myVar = -314.5;';  // what we get from the server
var match = script.match( /var\s+(\w+)\s*=\s*(-?[\d.]+)\s*;/ );
if( match ) {
    // match[1] is 'myVar', match[2] is '-314.5'
    context[ match[1] ] = +match[2];
}
console.log( context );

Now context is { myVar: -314.5 }. This code could be run inside a function or anywhere and would work the same.

You could use a similar regular expression for a string variable assignment:

var script = 'var myString = "Test Value";';  // what we get from the server
var match = script.match( /var\s+(\w+)\s*=\s*"([^"]*)"\s*;/ );
if( match ) {
    // match[1] is 'myString', match[2] is 'Test Value'
    context[ match[1] ] = match[2];
}
console.log( context );

This time, context is { myString: "Test Value" }

This approach could easily be adapted for multiple variables, other data types, etc.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • Thanks you, your approach works like a charm. I thought I was able to restrict the scope of eval() so that the declaration like var someVal would goes into this scope like that of global scope. – Ryan Jul 06 '15 at 01:25