-2

I am confused between using an IIFE vs using a normal function call (with parameters) inside a for loop.

Lets say the function is -

function print_doc_count(i){
    var str= "collection" + i.toString();
    db.collection(str).count(function(err, res){
        if(!err){
            console.log("docs in collection: "+str+" = "+res);
        }
    });
}


Example 1 (Without IIFE) -

for(var i=1; i<=10; i++){
    print_doc_count(i);
}

Example 2 (With IIFE) -

for(var i=1; i<=10; i++){
    (function print_doc_count(i){
        var str= "collection" + i.toString();
        db.collection(str).count(function(err, res){
            if(!err){
                console.log("docs in collection: "+str+" = "+res);
                // str needed closure, it contains the value i!
            }
        });
    })(i);
}


My question is what is the difference between Example1 and Example2 above and should one be preferred over the other (under what circumstances)?

vjjj
  • 1,019
  • 3
  • 10
  • 35
  • hmm... surely you meant to declare `str` within the iife rather than outside? with it declared outside you could (or, will) run into issues with it's value once the count callback occurs. Not entirely sure why you handled that differently in example 2 compared to example 1. both snippets seem to be attempting to get around the for loop closure problem, however only one of the two does so effectively due to the way `str` is declared. – Kevin B Nov 21 '16 at 19:19
  • I don't get you. Are you trying to compare an apple with an orange? – Gogol Nov 21 '16 at 19:20
  • @Gogol - will console.log not print similar results in both cases? – vjjj Nov 21 '16 at 19:21
  • Both of your options, used correctly, are viable solutions to the for loop closure problem. More modern solutions include using arrow functions, array iteration methods, and block scoped variables (let/const) – Kevin B Nov 21 '16 at 19:23
  • the difference is, one uses a previously defined function while the other creates a new function for each iteration. Obviously, the previously defined function route will be more performant. however, you could scrap both options and use `let` to solve the problem, removing the need for a function at all. – Kevin B Nov 21 '16 at 19:26
  • If you move the `str` declaration into the function, they will be the same. Otherwise they will all share the same `str` value if the callback was asynchronous. – 4castle Nov 21 '16 at 19:27
  • I think for the most part this question is a duplicate of http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example the end result is the same, while the intent of this question may be slightly different. but the answers there should provide all you need to answer this question. – Kevin B Nov 21 '16 at 19:30
  • @Kevin B - lets say using let/const is not a viable solution, and you say that IIFE is not performant wrt single function declaration. Then - should a function declaration be preferred whenever there is a question of creating a closure between function call vs IIFE? – vjjj Nov 21 '16 at 19:31
  • Yes, that would be a fair assessment. but you're using node, so... not sure why let/const wouldn't be viable. [It was available as far back as 0.12](http://stackoverflow.com/questions/28388885/ecmascript-6-features-available-in-node-js-0-12) – Kevin B Nov 21 '16 at 19:32

1 Answers1

0

As stated by @Kevin B in comments to the question, Example 1 (without IIFE) is a better solution

function print_doc_count(i){
    var str= "collection" + i.toString();
    db.collection(str).count(function(err, res){
        if(!err){
            console.log("docs in collection: "+str+" = "+res);
        }
    });
}

for(var i=1; i<=10; i++){
    print_doc_count(i);
}
vjjj
  • 1,019
  • 3
  • 10
  • 35