자바스크립트의 IIFE

DoonDoon·2019년 4월 7일
12
post-thumbnail
post-custom-banner

A banner is created from here

IIFE 란 정의와 동시에 즉시 실행되는 함수를 의미합니다
Immediately Invoked Function Expression (즉시 실행되는 함수 표현식) 의 약자입니다

IIFE 에 대해서 좀 더 명확하게 개념을 정리하기 위해
이 글을 작성하였습니다

잘못된 부분은 댓글을 남겨주시면 수정하도록 하겠습니다

Contents


  1. 즉시 실행 함수 표현식
  2. 즉시 실행 함수는 언제 사용하나요?
  3. 즉시 실행 함수의 다양한 표현식
  4. 화살표 함수와 즉시 실행 함수

즉시 실행 함수 표현식


즉시 실행 함수는 함수 리터럴() 로 감싼 뒤
바로 실행하는 형태가 일반적입니다

문장으로는 조금 모호하니 코드로 적어볼게요

(function () { console.log('Hello World') })(); // Hello World

자바스크립트의 함수 리터럴이란 무엇인지 잠시만 짚고 넘어가겠습니다

함수 리터럴 (Function Literal)


자바스크립트에서 함수를 정의하는 표현식을 "함수 리터럴" 이라고 합니다
함수 리터럴은 아래 4개의 요소로 구성됩니다

  1. 예약어 function (필수)
  2. 함수이름 (선택)
  3. 매개변수 집합 (필수)
  4. 함수 본문 (필수)

명칭은 거창하지만, 실제로는 일반적으로 다들 알고 있는
자바스크립트의 함수 선언을 위한 문법을 의미합니다

function add(a, b) {
  return a + b
}

아래처럼 이름 없는 함수로도 작성하면... 에러가 발생합니다

function (a, b) { return a + b } // Uncaught SyntaxError: Unexpected token (

함수 이름은 선택사항이라고 했지만,
함수 이름이 없이 정의하는 경우에는 아래 조건이 충족되어야 합니다

  1. 이 함수를 할당 받을 변수를 지정
  2. 이 함수를 즉시 호출

그러니까, 결국 이렇게 되어야 하는 거죠

const add = function (a, b) { return a + b };
(function(a, b) { return a + b })(1, 2); // 3

위와 같은 함수 리터럴 표현식을 통해 즉시 실행 함수를 정의할 수 있습니다
그리고 즉시 실행 함수라는건 바로 위 코드처럼
즉시 실행되어 값으로 평가되는 함수를 의미합니다

즉시 실행 함수는 언제 사용하나요?


즉시 실행 함수는 함수를 즉시 평가하여 값으로써 활용하는것에
그 의미가 있기 때문에, 꼬집어 그 용도를 정의하긴 어렵습니다

다만 보편적으로는 전역 스코프를 오염시키지 않기 위해 사용하는 경우가 많습니다

예를 들어, 어떤 버튼의 클릭 횟수를 추적하고
10번 이상 클릭한 뒤에는 클릭이 되지 않게 하고 싶다고 가정하겠습니다

전역 스코프에 클릭 횟수를 담는 변수를 만들어서 처리할 수도 있지만
아래와 같이 하면 전역 스코프를 오염시키지 않고 처리가 가능합니다

<body>
  <button id="button">버튼</button>
  <script type="text/javascript">
    const buttonHandler = (function () {
      let count = 0;
      return function(event) {
        if (count > 9) { // 클릭 횟수가 10번 이상일 때는 클릭이벤트 무시
          event.preventDefault();
          alert('🚫버튼을 열 번 이상 누르면 큰일납니다. 아무튼 큰일남')
          return;
        }
    
        count += 1; // 이렇게 자체 스코프에서 변수를 관리할 수 있습니다!
        /* ... 이하 버튼 처리 코드 ... */
      }
    })()

    document.querySelector('#button').addEventListener('click', buttonHandler)  
  </script>
</body>

사실 즉시 실행 함수를 사용함과 동시에, Closure 를 사용해서 가능한 일이긴 합니다
클로져에 대한 설명은 이 글 을 참고해주세요!

즉시 실행 함수의 다양한 표현식


즉시 실행 함수를 만드는 다양한 방법을 알아보기 전에
왜 즉시 실행 함수는 익명(기명도 가능하긴 하지만)함수를 () 로 감싸야만 할까요?

function() {} 과 같이 작성되면, 자바스크립트 코드를 해석하는 파서는
이것을 함수 선언문(statement) 으로 인지합니다.

(의 차이에 대해서는 긴 주제이기 때문에 이 글을 참고해 주세요)

문은 자바스크립트 해석기에게 명령을 지시하고 사라지는 것이기 때문에
"값"으로 남지 않습니다

따라서, () 와 같이 괄호로 묶어주어
이것은 "함수 선언문이 아닌 "함수 표현식" 이라는 것을
명시적으로 나타내야 합니다

익명함수를 값으로 나타내기 위해서는 (=함수 표현식으로 만들기 위해서는)
() 로 묶어주는 것 외에도, 연산자를 앞에 붙여줄 경우에는 모두 즉시 실행 됩니다

(자바스크립트의 연산자에 대한 설명은 MDN)

!function(a, b) { return console.log(a + b) }(1, 2) // 3
void function(a, b) { return console.log(a + b) }(1, 2) // 3
+function(a, b) { return console.log(a + b) }(1, 2) // 3
-function(a, b) { return console.log(a + b) }(1, 2) // 3
~function(a, b) { return console.log(a + b) }(1, 2) // 3
*function(a, b) { return console.log(a + b) }(1, 2) // 3
^function(a, b) { return console.log(a + b) }(1, 2) // 3
&function(a, b) { return console.log(a + b) }(1, 2) // 3
/* ... 등등 연산자를 앞에 붙이면 됩니다 ... */

보통은 () 로 묶는 표현 방법을 사용합니다 (eslint 기준)

(function(a, b) { return a + b })(1, 2) // 3

앞의 구문이 semi-colon 이 없어서, 이어서 값으로 평가되는 것을 방지하기 위해
아래와 같은 형태로도 사용합니다

;(function(a, b) { return a + b })(1, 2) // 3

IIFE 앞에 세미콜론을 붙여, ASI(자동 세미콜론 삽입) 처리가 되지 않았을 상황을 방지합니다

ASI?


자바스크립트는 문의 마지막에 세미콜론을 붙이지 않으면
알아서 세미콜론을 삽입하는 Automatic Semicolon Insertion 기능이 존재합니다

이에 대한 자세한 글은 자바스크립트 창시자인
브랜든 아이크의 블로그 글을 참고해주세요

화살표 함수와 즉시 실행 함수


화살표 함수는 => 화살표가 연산자가 아니고,
화살표 함수 자체의 파싱이 특별하게 취급 되기 때문에

() 로 묶어서 사용하는 방법 밖에는 동작하지 않습니다

((a, b) => a + b)(1, 2); // 3
!(a, b) => a + b)(1, 2); // Uncaught SyntaxError: Malformed arrow function parameter list

아래와 같이 ! 연산자를 사용한 즉시 실행 함수 표현식은 문법 오류가 발생합니다

마치며


파이썬을 실무에서 사용하는 제게 자바스크립트의 IIFE 는 너무 부러운 문법입니다 😥

음 게다가 파이썬의 가독성 안좋은 lambda 표현식 보다는
간결한 화살표 함수 또한 마찬가지로 부럽습니다...

코딩 중에 IIFE 에 대해 정확한 개념을 정리하고 싶어 작성한 글이
꽤나 길어지게 되었네요. 긴 글 읽어주셔서 감사합니다!

profile
Espresso Cream Cat DD
post-custom-banner

2개의 댓글

comment-user-thumbnail
2019년 4월 9일

항상 가려움을 느꼈던 주제입니다. 정리해 주셔서 감사합니다.

답글 달기
comment-user-thumbnail
2020년 11월 8일

PHP도 7.0 부터는 IIFE 되네요

답글 달기