Search code examples
javascriptfunctioneval

What does the expression eval(function(){ } ()) do in javascript?


I found this script on a web page:

eval(function(a, b, c, d, e, f) {
    //do some thing here and return value
}(val1, val2, val3, val4, val5, {}))

Do you know what above expression really does?


Solution

  • Let's unpack things one by one, first the inner part

    function(a, b, c, d, e, f) {
        //do some thing here and return value
    }(val1, val2, val3, val4, val5, {})
    

    In fact, let's simplify it even more

    (function() { //takes no paremeters
        console.log("this was executed");
    }())//no parameters given here

    This is called an immediately invoked function expression or very often shortened to IIFE. It is rather boring, honestly, the name is the entire description but let me rephrase - it's a function that is declared and then executed straight away. This is done by the final () brackets - exactly how you'd otherwise execute a function, for example parseInt(). In this simple case, it simply prints something to the console and finishes.

    However, it is a normal function and it can do anything you want, including take parameters:

    (function(param1, param2) { //takes two parameters
        console.log("this was executed with parameters", param1, param2);
    }("hello", "world"))//these are passed to the function

    So, you can do a lot more stuff. You can even return a value and the parameters passed to the function could be variables:

    var someVariable = "hello";
    var anotherVariable = "world";
    
    var resultFromIIFE = (function(param1, param2) { //takes two parameters
        console.log("this was executed with parameters", param1, param2);
        return param1 + param2;
    }(someVariable, anotherVariable));
    
    console.log(resultFromIIFE);

    So, hopefully that clears up the inner part. I'll get back to it.

    As for eval - it takes a string and executes it as JavaScript code.

    eval("console.log('this comes from eval()')");
    
    
    var evalCanReturnResults = eval("1 + 2");
    console.log(evalCanReturnResults);
    
    
    var a = 3;
    var b = 4;
    var evalCanUseVariables = eval("a + b");
    
    console.log(evalCanUseVariables);

    That's a quick crash course in eval. It's enough to understand that it can take any arbitrary string and execute it as JS.

    So, if we put the two together, the inner IIFE will most likely be generating some code dynamically for eval to execute. For example, you could have something like::

    eval(function(limit, toPrint) {
        return "for (var i = 0; i < " + limit + "; i++) { console.log('" + toPrint + "') }"
    }(3, "foo"))

    Which will generate a for loop with the parameters specified and execute it.