1

Yes I know eval is evil but ...

Few times I saw a function being created from a string in few different ways:

var s = "function fname() { this.m = function(s){alert(s);}}";

//1
var x = new( eval("("+s+")") );
x.m("aaa")

//2
var x = new( eval('[' + s + ']')[0] );
x.m("bbb")

//3
var x = new ( eval(s + " fname;") );
x.m("ccc")

The first 2 are clear to me but I wonder about the third one. Could someone explain how adding a name of the function after it's definition helps eval do the job ? Also do you know any other ways of using eval to create funcions ?

Thanks Szymon

szydan
  • 1,668
  • 1
  • 12
  • 16

2 Answers2

1

First, with the function declaration (which is not an expression), you create the function and put it into the current scope:

function fname() { ... }

The closing brace finishes the function statement, and an expression follows:

fname

As the function is already in the scope, the expression fname simply refers to the function. And because the expression is the last thing in your eval'ed code, eval returns exactly that function reference.

Instead of fname, you could write the name of any function in the current scope, e.g. alert, which would then be returned by eval.

Yogu
  • 8,033
  • 4
  • 31
  • 51
  • If it were a statement, it would contain an expression ([not allowed](http://es5.github.com/#x12.4) with functions). It is not, it is a [function *declaration*](http://es5.github.com/#x13) – Bergi Aug 05 '12 at 19:02
  • Thank you, corrected it. I wanted to emphasize that it's not an expression. – Yogu Aug 05 '12 at 19:05
  • Thank you both Yogu and Bergi To make it even more clear maybe we add a sentece saying that "to return something Eval needs something which return something (an expression)" Would that be correct ? – szydan Aug 06 '12 at 11:54
  • So you understood what I mean? I've edited it and hope it's now a bit clearer. – Yogu Aug 06 '12 at 20:17
0
function fname() { this.m = function(s){alert(s);}}

is a function declaration. Eval would create it, but not return it, so after it another statement is added that just evaluates to the function reference.

In the other two examples it will be a function expression (with brackets around, or inside array literal), which itself evaluates to the reference.

Community
  • 1
  • 1
Bergi
  • 513,640
  • 108
  • 821
  • 1,164