IIFE (즉시실행함수)와 Closure

Marullo·2021년 4월 9일
1
post-thumbnail

IIFE(Immediately Invoked Function Expression)

함수는 함수를 정의하고, 변수에 함수를 저장하고, 실행하는 과정을 필요로하는데,
표현식으로 바꾼 함수를 바로 호출하게 되면, 정의를 하자마자 바로 실행된다.
이렇게 함수 정의가 끝나자마자 호출하는 것을 즉시실행함수라고 한다.


먼저, Statement와 Expression

표현식(expression)은 한 번 실행하기 위해 사용된다.
모든 코드를 메모리에 상주시킬 필요가 없다.
expression은 실행될 때만 메모리에 로드되고, 실행이 끝나면 메모리에서 사라진다.

문(Statement)은 expression을 재활용하기 위해 사용된다.
보통 statement는 메모리 주소의 별칭(흔히 변수명,함수명)에 할당되어 다시 사용되곤 한다.
따라서 statement는 메모리에 계속 상주한다.



함수를 표현식으로

즉시실행함수는 "표현식"으로 바뀐 함수를 바로 실행하는 것이다.
이러한 즉시실행함수의 장점은 실행 후 휘발되는 것인데, 함수 선언문은 Scope에 저장된다.
따라서 즉시실행함수를 만드려면, 함수를 표현식으로 만들어야한다.

함수를 표현식으로 바꾸기 위해 그룹핑연산자를 사용하거나 (function get(){ })
혹은 !function get(){ }를 사용한다.

  • 그룹핑 연산자는 괄호() 안에 위치한 표현식의 결과를 반환해준다.
  • 이 경우에는 !에 의해, 엔진이 뒤에 있는 함수를 표현식으로 인식하게 된다.

익명함수 이용

익명함수를 그냥 사용하면, Function Statement의 Syntax Error가 발생한다.
그러나, 표현식으로 바꾸면 익명함수도 사용 가능하다.
따라서 (function(){ }) 혹은 !function(){ } 처럼 사용이 가능하다.



호출

표현식으로 바꾼 함수를 호출하려면 ()를 붙여주면 된다.
result = !function(){ return 100 }()
즉시 실행되고 반환 값을 바로 넘겨주게 된다.



쓰임

IIFE를 변수에 할당하면 IIFE 자체는 저장되지 않고, 함수가 실행된 결과만 저장된다.
전역 스코프에 불필요한 변수를 추가해서 오염시키는 것을 방지할 수 있을 뿐 아니라
IIFE 내부안으로 다른 변수들이 접근하는 것을 막을 수 있다.

1. 초기화

statement는 expression을 여러 번 사용하기 위해 쓰이는 반면, expression은 한 번 쓰기 위해 사용된다.
즉시실행함수는 함수를 표현식으로 바꾸고 바로 실행하는 것이기 때문에, 한 번 쓰기 위해 사용한다고 봐도 무방할 것이다. 따라서 즉시실행함수는 한 번의 실행만 필요로 하는 초기화부분에서 많이 사용된다.

그런데 굳이 즉시실행함수를 쓰는 이유는 Global Scope를 깔끔하게 유지하기 위함이다.
즉시실행함수는 실행될 때만 메모리에 존재하고, 실행이 끝나면 메모리에서 날린다.
따라서 "즉시실행함수의 이름"은 Global Scope에 저장되지 않는다.


2. 이름 충돌 방지

ES6 이전에는 JS가 Module을 지원해주지 않아, 이름충돌을 방지하기 위해 쓰였다.
요즘은 JS Module 시스템이나, Module 기반의 bundler를 사용하면서, Global Scope에서 이름 충돌 현상은 발생하지 않는다. 따라서 요즘은 이름 충돌 방지를 위해서 사용하지는 않는 것 같다.


3. Closure와 IIFE

Closure는 캡슐화된 변수에 접근 가능한 함수다.
Closure와 IIFE를 함께 사용하면 어떤 장점이 있을까.

IIFE의 휘발성을 떠올리자. Closure를 반환하는 함수(부모 함수라고 하겠다.)는 Closure를 반환하고 나서 휘발된다. 부모함수는 내부 변수를 선언하고 Closure를 반환하는 역할을 할 뿐, 이후에는 다시 사용되는 경우가 거의 없다.

따라서 Global Scope에 다시는 사용되지 않을 부모함수를 남기지 않기 위해, 부모함수를 즉시실행함수로 만들어 Global Scope의 오염을 방지한다. 이렇게 오염을 방지하면, 이름충돌현상에 의해 변수에 대한 작업이 이상해지는 것을 막을 수 있다.

let closure = (function(){
  let point = 100
  return function(){ 
    return ++point 
  }
})()

console.log(closure()) //=> 101
console.log(closure()) //=> 102
profile
한국외대 중국어&컴공 복수전공 - 세미 전공자의 기술 블로그

0개의 댓글

관련 채용 정보