LEARNING JAVASCRIPT - Trang 214

function

loopBody

(

i

) {

setTimeout

(

function

() {

console

.

log

(

i

===

0

?

"go!"

:

i

);

}, (

5

-

i

)

*

1000

);

}

var

i

;

for

(

i

=

5

;

i

>

0

;

i

--

) {

loopBody

(

i

);

}

At each step in the loop, the function

loopBody

is invoked. Recall how arguments are

passed in JavaScript: by value. So at each step, it’s not the variable

i

that gets passed

into the function, but the value of

i

. So the first time, the value

5

is passed in, the

second time the value

4

, and so on. It doesn’t matter that we use the same variable

name (

i

) in both places: we’re essentially creating six different scopes and six inde‐

pendent variables (one for the outer scope, and five for each of the

loopBody

invoca‐

tions).
Creating a named function for loops that you are only going to use once can get tedi‐

ous, though. Enter IIFEs: they essentially create equivalent anonymous functions that

are invoked immediately. Here’s how the previous example looks with an IIFE:

var

i

;

for

(

i

=

5

;

i

>

0

;

i

--

) {

(

function

(

i

) {

setTimeout

(

function

() {

console

.

log

(

i

===

0

?

"go!"

:

i

);

}, (

5

-

i

)

*

1000

);

})(

i

);

}

That’s a lot of parentheses! If you think about it, though, the exact same thing is being

accomplished: we’re creating a function that takes a single argument, and invokes it

for each step in the loop (see

Figure 13-1

for a visual explanation).

Figure 13-1. Immediately invoked function expression

190 | Chapter 13: Functions and the Power of Abstract Thinking