Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a Javascript function created with Function constructor unable to access other functions defined outside of it?

See the code below. Why does test2() cause an error while test1() does not? How can the error be avoided (without having to redefine the called function inside the constructor)?

function getRandomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }
var xyz = function (){
                var test1 = function () { getRandomInt(10, 20); };
                test1();  // runs with out problem 
                var test2 = new Function('getRandomInt(10, 20);');
                test2(); //results in "Uncaught ReferenceError: getRandomInt is not defined"
                };
like image 716
Jarnal Avatar asked Mar 23 '23 04:03

Jarnal


2 Answers

I'm assuming all that is inside another function (an IIFE, maybe?). Code created with new Function is evaluated in the global scope, and it seems getRandomInt is not available there.

Check these demonstrations on jsfiddle: it works if unwrapped, but not inside an IIFE.

If you need the code to be evaluated in the current scope, you have to use eval:

var test2 = eval('(function(){return getRandomInt(10, 20);})');

http://jsfiddle.net/7wPK4/2/

References

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
  • http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.2.1
like image 143
bfavaretto Avatar answered Mar 24 '23 16:03

bfavaretto


I found this on MDN:

Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called. This is different from using eval with code for a function expression.

So maybe your getRandomInt isn't in the global scope? Would need to see the entire code, or a jsFiddle re-creating the problem.

like image 28
Joe Simmons Avatar answered Mar 24 '23 17:03

Joe Simmons