IIFE (Immediately-Invoked Function Expression)
기본적으로 함수(function)란, 특정 컨텍스트에서 적절한 순서로 실행되는 명령문 모음이다. 이중 IIFE는 "즉시 호출되는 함수 표현식"이다.
함수 선언(Function Declaration)과 함수 표현(Function Expression)의 차이는?
// declaration
function func() {}
// expression
const func = function func() {}
함수 선언은 중복될 수 있다는 문제점이 있다. 마지막에 만든 함수가 적용된다는 것. 즉, 호이스팅 문제. 반면 함수 선언문보다 안전한 게 바로 함수 표현식. 즉, 선언한 함수를 변수에 할당하는 것. 중복 선언과 호이스팅 문제를 변수에 위임하는 것을 말한다.
함수 표현식보다 더 안전한 게 "익명함수 표현식"
const func = function() {}
함수 선언의 경우 미리 자바스크립트 실행 컨텍스트에 로딩되어 있으므로 언제든지 호출할 수 있지만, 표현식은 인터프리터가 해당 라인에 도달했을 때만 실행된다(이것 때문에 호이스팅을 막을 수 있음).
예를 들어 함수 선언의 경우 함수명()
만 작성하면 언제든지 호출할 수 있지만, 함수 표현식은 인터프리터가 해당 변수가 도달했을 때만 실행된다.
괄호() 안에 있는 코드를 바로 실행해달라는 명령어
;(function () {
'use strict'
const init = () => {
window.addEventListener('DOMContentLoaded', () => {
getTodos()
})
}
init()
})()
원래 보통은 함수를 실행하기 위해 함수명()을 작성해야만 실행되지만, 함수에 괄호를 감싸주면 이 함수가 즉시 실행되는 함수가 된다.
// 일반적인 함수 실행
function func () {}
func()
// 즉시 실행 함수 표현식
(function func () {})();
예를 들어,
var root = (function() { return document.documentElement || document.body })();
console.log(root); // <html />
var root2 = function() { return document.documentElement || document.body };
console.log(root2); // function() { return ... }
위 코드를 보면, IIFE를 사용하지 않으면 함수의 return 값이 변수에 할당되는 게 아니라 함수 자체가 변수에 할당되어 버린다.
IIFE를 사용하는 이유
IIFE 사용 예제
(function (window, document, undefined) {
// ...
})(window, document);
위 코드를 아래 코드처럼 압축할 수 있다.
(function (a,b,c) {
// ...
})(window, document);
이외에도 함수를 괄호로 감싸는 대신, 다른 방식으로 함수를 함수표현식으로 유도하는 방법들 존재
!function() {}
+function() {}
-function() {}
~function() {}
void function() {}
return function() {}
new function() {}
0,function() {}
1&&function() {}
...
예를 들어, 아래 코드를 보면 계속해서 6을 출력한다. 왜냐하면 자바스크립트는 비동기 코드(예를 들어, setTimeout 등)를 만나면 비동기 작업이 완료될 때까지 콜백 실행을 연기하기 때문이다.
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log('I reached step ' + i);
}, 1000 * i);
}
/* result
I reached step 6
I reached step 6
I reached step 6
I reached step 6
I reached step 6
*/
이 문제를 IIFE로 해결할 수 있다.
for (var i = 1; i <= 5; i++) {
(function (step) {
setTimeout(function() {
console.log('I reached step ' + step);
}, 1000 * i);
})(i);
}
/* result
I reached step 1
I reached step 2
I reached step 3
I reached step 4
I reached step 5
*/
참고
JavaScript's Immediately Invoked Function Expressions
Immediately Invoked Function Expressions (IIFE) in JavaScript