IIFE (Immediately Invoked Funtion Expressions)?

IIFE(즉시 호출 함수 표현식)은 주로 이름 충돌 최소화 및 private 변수 생성에 사용되는 자바스크립트 디자인 패턴이다.
(function(){ 
  console.log('IIFE'); 
})();

함수 표현식으로서 익명 또는 기명 함수를 만들고는, 그 즉시 함수 호출을 함

 

"이 안에 들어있는 코드를 바로 실행하라" 하는 표현으로 이해하자.

 

 

함수 선언문과 함수 표현식?

함수 선언은 함수 이름을 생략할 수 없고, 자바스크립트의 실행 컨텍스트에 로딩되어 있으므로 언제든지 호출할 수 있다.

함수 표현식은 값으로서 평가되며, 익명함수로 나타낼 수 있고, 인터프리터가 해당 라인에 도달하였을 때만 실행됨

 

함수 선언을 괄호 연산자로 그룹핑해주면 함수 표현식으로 나타낼 수 있다.

halo() //호이스팅으로 인해 오류가 나지 않는다, 출력: halo

function halo() {
  console.log('halo')
}


// 익명함수로 사용
(function(){
	console.log("foo")
})() //출력: foo

// 기명함수로 사용
(function foo() {
    console.log('foo')
})() // 함수선언문이 함수표현식으로 바뀌었고 IIFE로 인해서 즉시 호출된다, 출력: foo

foo() //ReferenceError: foo is not defined
//함수 이름인 foo는 함수 몸체에서만 참조할 수 있는 식별자이므로 IIFE를 다시 호출할 수 없다.

 

IIFE의 구조

일반적으로 아래와 같은 두가지 방법으로 사용한다

(function(){ console.log('IIFE'); })();
( function(){ console.log('IIFE'); }() );

ES6에서 도입된 화살표함수도 함께 사용할 수 있다.

(() => console.log('IIFE with arrow'))();

(() => {
    console.log('IIFE with arrow')
})()

 

언제, 왜 사용하나요?

1. 이름 충돌 최소화

=> 불필요한 전역 변수와 함수를 생성하지 않는 것이 좋다

 

프로그램 초기화 시점에 init 함수를 실행한다고 가정하자.

function init() {
  var operate = 'init';
  console.log(operate)
}
init()

이 함수는 전역 scope에 선언되어 이름 충돌이 발생할 확률이 높다. 

개발자 의도와는 달리, 다른 코드에서 init 함수가 재호출될 수도 있다.

(function init() {
  var operate = 'init';
  console.log(operate)
})()

따라서, 외부 코드로부터 사용되지 않는, 단 한 번 호출하는 코드들, 변수와 함수들은 IIFE를 사용하여 전역 scope 오염을 방지하고 다른 개발자가 실수로 호출할 수 없게 해준다.

=> 즉시 실행한 뒤에 전역에서 사라지기 때문에 전역 scope와 충돌하지 않는 것이다.

 

2. clousure와 private 데이터

IFE의 장점은 내부에 있는 것들이 모두 자신만의 스코프를 가지지만, IIFE 자체는 함수이므로 스코프 밖으로 무언가를 내보낼 수 있다는 것이다.

const greet = (function() {
	const secret = "비밀"
return `비밀의 길이는 ${secret.length}이다.`;
})()

console.log(greet) //비밀의 길이는 2 이다

변수 secret은 IIFE 스코프 안에서 안전하게 보호되며 외부에서 접근할 수도 없다.

 

IIFE는 함수이므로 무엇이든 반환할 수 있으며, 배열, 객체, 함수를 반환할 수도 있다

const getCount = (function(){
  let count = 0;
  return function() {
    ++count;
    return count;
  }
})();

console.log(getCount()); // 1
console.log(getCount()); // 2

IIFE 안의 익명함수는 closure가 되며, 변수 count는 private data로, IIFE 안에 안전하게 보관되어 있으므로 전역에서 접근이 안된다.

  • getCount 변수외부함수(IIFE)를 실행한 결과를 저장한다. 처음 한번만 실행되기 때문에 count는 0으로 저장되며 내부함수(익명함수)를 반환한다.
  • getCount()가 호출될 때마다 내부함수가 실행되기 때문에 count변수가 증가하고 반환되기 때문에 콘솔에 나타나는 것은 내부 함수에서 반환한 업데이트된 count값이다.

 

이를 모듈 패턴이라고도 한다. (클로저를 기반으로 동작하면서, 전역변수의 억제는 물론 캡슐화까지 구현)

 

3. 변수의 별칭

만약, jQuery와 또다른 라이브러리를 사용하고 있는데, 둘다 $을 전역 변수로 사용한다면 충돌 문제가 생길 수 있다.

이럴 때, jQuery를 인자로 받는 IIFE 블럭으로 감싸주면 블록 내의 $가 jQuery로 정의되면서 충돌을 방지할 수 있게 된다.

(function($) {
  //예시 코드
   $("p").on("click", function() {
       $("p").css("color", "red");
    });
})(jQuery)

 

4. 자주 사용되는 특정한 키워드를 압축

(function(window, document, undefined) {
   window.alert("안녕")
   document.write("반가워")
})(window, document);

이 코드를 압축해보면,

(function(a, b, c) {
   a.alert("안녕")
   b.write("반가워")
})(window, document);

매개변수로 받은 window, document, undefined를 a,b,c 라는 토큰으로 지정해주기 때문에 

이 IIFE 블록 내에 있는 모든 window 키워드는 a로 대체할 수 있다.

-> 스크립트가 길면 길수록, 이 방식으로 파일의 용량을 크게 줄일 수 있다.

 

 

참고, 출처:

https://velog.io/@bisu8018/JS-IIFEImmediately-Invoked-Function-Expressions-%EB%9E%80

http://chanlee.github.io/2014/01/11/understand-javascript-iife/

https://medium.com/sjk5766/iife-immediately-invoked-function-expression-%EC%A0%95%EB%A6%AC-53ab6543b828

https://findawayer.tistory.com/entry/IIE%EC%9D%98-%EC%9D%98%EB%AF%B8%EB%8A%94

https://code-masterjung.tistory.com/65

'엘리스 ai 트랙 > FE' 카테고리의 다른 글

기본값+rest+spread  (0) 2022.03.07
구조분해할당  (0) 2022.03.07
var vs let vs const  (0) 2022.02.21
스코프  (0) 2022.02.14
BFC (Block Formatting Context)  (0) 2022.02.05

+ Recent posts