๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

[Hard] ๐Ÿ“„ IIFE

1. What's the IIFE ?โ€‹

IIFE๋Š” ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜ ํ‘œํ˜„์‹์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ์ผ๋ฐ˜ ํ•จ์ˆ˜์™€ ์ž‘์„ฑ๋ฒ•์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์™ธ๋ถ€์— ()๋ฅผ ํ•œ ๊ฒน ๋” ๊ฐ์‹ธ์•ผ ํ•˜๋ฉฐ, ์ฆ‰์‹œ ์‹คํ–‰๋˜๋Š” ํŠน์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค:

(() => {
console.log(1);
})();

# or

(function () {
console.log(2);
})();

์ด ์™ธ์—๋„ recursion(์žฌ๊ท€)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ค‘๋‹จ ์กฐ๊ฑด์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋๋ถ€๋ถ„์˜ ()๋กœ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(function myIIFE() {
num += 1;
console.log(num);
return num < 5 ? myIIFE(num) : console.log('finished!!');
})((num = 0));

๋‹ค๋งŒ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€, IIFE๋Š” ์ดˆ๊ธฐ ์‹คํ–‰ ์‹œ์—๋งŒ ์‹คํ–‰๋˜๊ฑฐ๋‚˜ ๋‚ด๋ถ€์—์„œ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์„ ๋ฟ, ์™ธ๋ถ€์—์„œ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

2. Why use IIFE ?โ€‹

scopeโ€‹

๋ณ€์ˆ˜๊ฐ€ function ๋‚ด์—์„œ ์†Œ๋ฉธ๋˜๋Š” ํŠน์„ฑ์„ ์ด์šฉํ•˜์—ฌ, IIFE๋กœ ์Šค์ฝ”ํ”„๋ฅผ ๊ฒฉ๋ฆฌํ•˜๊ณ  ์ „์—ญ ๋ณ€์ˆ˜์˜ ์˜ค์—ผ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”:

// global
const name = 'Yumi';
const Hello = () => {
return `Hello ${name}!`;
};

(() => {
const name = 'Pitt';
const Hello = () => {
return `Hello ${name}!`;
};
console.log(name); // result Pitt
console.log(Hello()); // result Hello Pitt!
})();

console.log(name); // result Yumi
console.log(Hello()); // result Hello Yumi!

private variable and methodsโ€‹

IIFE์™€ closure๋ฅผ ๊ฒฐํ•ฉํ•˜๋ฉด Private variable and methods๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, function ๋‚ด์— ๋ณ€์ˆ˜๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ํ•ด๋‹น function์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ์ด์ „ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ’์„ ์กฐ์ •(์ฆ๊ฐ€ ๋˜๋Š” ๊ฐ์†Œ ๋“ฑ)ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const increment = (() => {
let result = 0;
console.log(result);
const credits = (num) => {
console.log(`I have ${num} credits.`);
};
return () => {
result += 1;
credits(result);
};
})();

increment(); // I have 1 credits.
increment(); // I have 2 credits.

๋‹ค๋งŒ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€, ๋ณ€์ˆ˜๊ฐ€ ์†Œ๋ฉธ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‚จ์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜์—ฌ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

moduleโ€‹

๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์‹คํ–‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์‹œ๋ฅผ ๋ณด๋ฉด ๋ณ€์ˆ˜ ์ฆ๊ฐ€๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ดˆ๊ธฐํ™”๋„ ๊ฐ€๋Šฅํ•จ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

const Score = (() => {
let result = 0;

return {
current: () => {
return result;
},

increment: () => {
result += 1;
},

reset: () => {
result = 0;
},
};
})();

Score.increment();
console.log(Score.current()); // result 1 => 0 + 1 = 1
Score.increment();
console.log(Score.current()); // result 2 => 1 + 1 = 2
Score.reset();
console.log(Score.current()); // result 0 => reset = 0

๋‹ค๋ฅธ ์ž‘์„ฑ ๋ฐฉ๋ฒ•:

const Score = (() => {
let result = 0;
const current = () => {
return result;
};

const increment = () => {
result += 1;
};

const reset = () => {
result = 0;
};

return {
current: current,
increment: increment,
reset: reset,
};
})();

Score.increment();
console.log(Score.current());
Score.increment();
console.log(Score.current());
Score.reset();
console.log(Score.current());

๋งˆ์ง€๋ง‰์œผ๋กœ ํŠนํžˆ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€, IIFE์˜ ์ฆ‰์‹œ ์‹คํ–‰ ํŠน์„ฑ ๋•Œ๋ฌธ์— ์—ฐ์†๋œ ๋‘ ๊ฐœ์˜ ์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ASI(์ž๋™ ์„ธ๋ฏธ์ฝœ๋ก  ์‚ฝ์ž…) ๊ทœ์น™์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฐ์†๋œ ๋‘ ๊ฐœ์˜ IIFE๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ง์ ‘ ์„ธ๋ฏธ์ฝœ๋ก ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.