-1
function SomeFunc()
{
    this.var1 = 123;
    this.evalStr = "console.log('myvar:' + this.var1)";
}

var sf = new SomeFunc();

eval(sf.evalStr); // returns "myvar: undefined"

I'd like eval to take into account variables on my instantiated object, how can I do this?

EDIT: that question you marked as duplicate is way more complex than what I'm asking. I'm talking about evaling a string here.

EDIT: hey my question shouldn't get downvoted just because I dared to say "eval". sheesh. if you look down you'll see the answers are quite useful.

Shai UI
  • 50,568
  • 73
  • 204
  • 309
  • Do you **have** to use `eval`? Surely there's a better way – Phil Mar 03 '17 at 03:29
  • yes I have to use eval – Shai UI Mar 03 '17 at 03:29
  • `eval` executes code in the callee local context. In your case, `this` is global context, i.e. `window`. – Yeldar Kurmangaliyev Mar 03 '17 at 03:33
  • Is this helpful? http://stackoverflow.com/questions/8403108/calling-eval-in-particular-context – Alexander Nied Mar 03 '17 at 03:34
  • 3
    If you really need to use `eval` so badly, please have the courtesy to tell us why. Right now, your question amounts to "I need to use `eval`, trust me. Now tell me how to do this awkward thing with it." – JLRishe Mar 03 '17 at 03:38
  • 1
    You probably don’t have to use `eval`. – Ry- Mar 03 '17 at 03:39
  • I'm using a content editable div just for that function. So the user can edit that code using a web based ide and run it. – Shai UI Mar 03 '17 at 03:41
  • `this.evalFn = function() {console.log("myval:" + this.var1); };`. Then, do `sf.evalFn()`. –  Mar 03 '17 at 03:42
  • torazaburo, I want my eval func as a string – Shai UI Mar 03 '17 at 03:42
  • Why do you want the eval func as a string? –  Mar 03 '17 at 03:43
  • 1
    Sounds like `sf.editableFunction = new Function("console.log('myvar: ' + this.var1);"); sf.editableFunction();` is closer to what you need, then. – Ry- Mar 03 '17 at 03:44
  • also, this code is not for end users. just for me so can be as hacky as heart's content. – Shai UI Mar 03 '17 at 03:49
  • @Ryan - Why the empty-string first argument? – nnnnnn Mar 03 '17 at 03:51
  • @nnnnnn: Personal preference (I don’t like overloads that shift arguments left). Will take it out for here. – Ry- Mar 03 '17 at 03:52
  • what do you mean by "new Function" isn't that a reserved word. also, if you can answer down there I can give you props – Shai UI Mar 03 '17 at 03:55
  • You’re getting downvoted because your question has an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), not because you mentioned `eval`. Having a lot of reputation doesn’t mean you automatically write good questions. But you can edit it to reflect the problem you’re actually trying to solve. – Ry- Mar 03 '17 at 04:16

2 Answers2

2

The evalInContext function in the first answer to this question does exactly what you're asking for. Just call it with sf.evalStr and sf:

function SomeFunc() {
  this.var1 = 123;
  this.evalStr = "console.log('myvar:' + this.var1)";
}

var sf = new SomeFunc();

function evalInContext(js, context) {
  return function() {
    return eval(js);
  }.call(context);
}
evalInContext(sf.evalStr, sf); // logs myvar:123

However, you'd be much better off using a constructed function. They're not quite as horrible as eval():

function SomeFunc() {
  this.var1 = 123;
  this.evalStr = "console.log('myvar:' + this.var1)";
}

var sf = new SomeFunc();

new Function(sf.evalStr).call(sf);  // logs myvar:123
Community
  • 1
  • 1
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • hot damn this was the answer I was looking for! – Shai UI Mar 03 '17 at 03:57
  • fwiw, i think this answer's 2nd part is the way to go, i was just showing how to give the meaning to `this` you specifically asked for, but `Function` is leaner and meaner. it's actually a good question, even if you get drive-bys from evalphobes... – dandavis Mar 03 '17 at 04:05
  • yeah I'm kind of digging this new Function() thing. never saw that until today. I did like your answer too though. – Shai UI Mar 03 '17 at 04:12
  • @foreyez The Run code snippet button creates an iframe that posts a request to http://stacksnippets.net/js, which returns an HTML page containing the JavaScript that was entered and that JavaScript executes. So no, it doesn't use `new Function()` or `eval()`. – JLRishe Mar 03 '17 at 07:23
1

perhaps you need something like this:

function SomeFunc()
{
    this.var1 = 123;
    this.evalStr = "console.log('myvar:' + this.var1)";
    this.eval = function(){return eval(this.evalStr)};
}

var sf = new SomeFunc();

sf.eval(); // returns "myvar: 123"

that keeps the context inside the constructor, where this means what you think it means.

If you want to keep it external, you have to use Function to give this meaning in dynamic code. In older versions of firefox, a 2nd argument to eval would provide context, but that functionality was deprecated and removed, probably because Function can handle that use-case.

dandavis
  • 16,370
  • 5
  • 40
  • 36