4

Is there a way to create a function at runtime with content that is unknown (but trusted) at design-time WITHOUT using eval()?

Basically I am trying to create a "hard coded" function for performance reasons as it is going to be called many, many times. Only the "hard coding" will be done once at runtime just before the many calls begin.

(untested example)

var strFuncString = 'function(){';
for (some loop)
{
    strFuncString+='DoSomething()'; //if this can be made to reference an object obtained for the for-loop then even better - i.e. Myfunc+=Obj.DoSomething
}
var MyFunc = eval(strFuncString  '}');

SomeProcessThatCallsItsArgALot(MyFunc);

I tried this in the debugger but unsurprisingly it didn't work

((function(){console.log(1);} )+( function(){console.log(2);}))()
Satpal
  • 132,252
  • 13
  • 159
  • 168
DJL
  • 2,060
  • 3
  • 20
  • 39
  • You can use `new Function`, but it works quite like `eval`. – Bergi Jun 05 '13 at 10:52
  • 3
    without using `eval` I don't think there is a way. But if it is a trusted source why not use eval? – Arun P Johny Jun 05 '13 at 10:53
  • 1
    And using a closure is too slow for you? The JIT should be capable of doing that on its own. Is this premature optimisation or did you already encounter some issues? – Bergi Jun 05 '13 at 10:54
  • possible duplicate of [new Function() with variable parameters](http://stackoverflow.com/questions/4183591/new-function-with-variable-parameters) – Evan Trimboli Jun 05 '13 at 10:55
  • I'm curious to what the restriction or requirement is that is the reason for this design. Seems like the actual problem is on a higher level. – MarioDS Jun 05 '13 at 10:56
  • @Bergi could you please expand some more? I just did a quick search on closures, I guess I already do that quite a lot but I don't see how it is relevant to the question?. As for premature optimisation - I might well be jumping the gun on streamlining this particular case however I believe the question is still valid. – DJL Jun 05 '13 at 11:59
  • I just mean `MyFunc = function(){ for (some loop) DoSomethin(); }`. And you might need a closure for the *some loop* so that it won't change, but probably you already have. – Bergi Jun 05 '13 at 13:51
  • @Bergi ok so the DoSomething() is an inexpensive operation so given the number so times this function was likely to be called (12k) I was hoping to avoid the (admittedly small) overhead of the for loop (over a handful of items) within the dynamically created function. – DJL Jun 05 '13 at 15:56
  • But the `DoSomething` function call has much more overhead than the loop? If anything, you should inline that function (though a JIT will do that anyway) – Bergi Jun 05 '13 at 15:59

1 Answers1

4

You can use new Function(bodytext).

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • Although I believe this is very similar to using `eval` – Ian Jun 05 '13 at 10:59
  • 1
    @Ian yes, it's similar, but doesn't appear to be tainted the way `eval` is, perhaps because it does guarantee that all you can get out is a function with its own scope. – Alnitak Jun 05 '13 at 11:00