본문 바로가기
Woowa Techcourse/Missions

Javascript IIFE(Immediately Invoked Function Expression)

by mingule 2021. 3. 10.

함수 선언식과 표현식 (맛보기)

즉시 실행 함수 표현에 대해 알아보려면 먼저 함수 선언식과 표현식에 대해 알아야한다.

아래와 같이 쓰는 것을 함수 선언식이라고 한다. 함수 선언식은 호이스팅에 영향을 받는다.

function 함수이름() {
  ...statements
}

아래와 같이 표현한 것을 함수 표현식이라고 한다. 함수 표현식은 호이스팅에 영향을 받지 않는다.

var 함수이름 = function() {
  ...statements
}

IIFE(Immediately Invoked Function Expression) : 즉시 실행 함수 표현

iffy는 말 그대로 정의되자마자 즉시 실행되는 함수를 말한다. 이러한 즉시 실행 함수는 global Scope 를 오염시키지 않기 위해 사용한다.

다양한 라이브러리들도 IIFE 패턴을 사용해 충돌을 방지하고 있다.

아래와 같이 작성할 수 있다. (1,2번이 자주 사용되고, 나머지는 그냥 알고만 있으면 된다.)

연산자를 사용한 방식은 return값이 있을 때 예상치 못한 결과가 나타날 수 있기 때문에 1,2방식이 더 널리 활용된다.

// 1.
(function() {
	...statements
})();

// 2. 
(function () {
  ...statements
}());

// 3.
!function() {
	...statements
})();

// 4.
+function() {
	...statements
})();

// 5.
void function() {
	...statements
})();
...

 

Javascript는 function 이라는 키워드를 볼 때마다, 함수의 정의가 일어날 것이라고 예측한다. 그래서 그런 정의가 일어나지 않는다는 것을 알려주려고 function 키워드 앞에 !를 붙여준다. 이렇게 하면 자바스크립트는 !뒤에 무엇이 오든 표현식으로 다루게 된다. ! 뿐만아니고 +, -, ~ 등 1진 연산자에 한해서 다양한 연산자를 붙여도 같은 결과를 보인다. 단순히 뒤에 나오는 함수를 식으로 만드는 것이니까! 

그니까 앞에 1진 연산자를 붙임으로서 작성한 함수가 정의되는게 아니고 으로 표현되게 만들어 그 함수를 즉시 실행하는 것이다. 마지막의 void는 함수를 식으로 다루어지게 강제한다. 반환 값이 필요없고 단순 실행만 하기를 원한다면 이렇게 사용하면 된다.

 

같은 선 상에서 이런 즉시 실행 함수 표현식은 "식"의 한 종류이기 때문에, 앞서 말했던 호이스팅이 발생하지 않는다. 아래와 같이 예시를 들 수 있다.

// 함수 선언식
boo(); // 실행된다.
function boo() {
	alert('booo!')
}

// 함수 표현식 
bhoo(); // 실행되지 않는다.
var bhoo = function () {
	alert('bhooo!')
}

// 즉시 호출 함수 
(function hoo() {})();
alert(hoo()) // hoo not defined

 

즉시 실행 함수 표현의 장점

- 전역 스코프에 불필요한 변수를 추가해서 오염시키는 것을 방지할 수 있다.

- IIFE 내부 안으로 다른 변수들이 접근하는 것을 막을 수 있다. 

- 값을 리턴해 변수에 할당할 수 있다.

- 호출될 때, 인자를 받을 수 있다.

 

아래의 예시를 통해 init()함수는 그 함수 바깥의 변수에 접근이 가능하지만, 바깥에서는 init 안으로 접근하지 못한다는 것을 알 수 있다.

(function example() {
  // 즉시실행함수 밖에서는 사용할 수 없는 변수들
  const a;
  const b;
  init();
    
  // 즉시실행함수 밖에서는 사용할 수 없는 함수
  function init() {
    a=1;
    b=2;
  }
}());

아래의 예시에서는 즉시실행함수를 통해 반환된 'result입니다.'라는 string이 result 변수에 할당되는 것을 알 수 있다.

const result = (function() {
  return 'result입니다.';
}());

alert(result) // 'result입니다.' 출력

IIFE는 호출시 인자를 전달할 수도 있는데, 아래와 같이 사용한다.

(function(count) {
    for(let i=0; i<count; i++)
        console.log("I am IIFE");
})(3);

 

예시

// 예제 1.
const message = (function() {
    const secret = "I m scret!";
    return `The secret is ${secret.length} characters long.`
})();
console.log(message); //The secret is 10 characters long.

// 예제 2.
// 호출된 함수를 가지고 있는 변수 f
const f = (function() {
    let count = 0;
    return function() {
        return `i have been called ${++count} time(s).`
    }
})();

f(); // "i have been called 1 time(s)."
f(); // "i have been called 2 time(s)."

1의 예시에서 secret은 외부에서 접근할 수 없기 때문에 안전하게 보호된다.

2의 예시에서는 함수를 호출할 때마다 새로 연산되어 값이 리턴되는 것을 알 수 있다.

 

참고 문헌 

 

자바스크립트 개발자라면 알아야 할 33가지 개념 #8 자바스크립트 필수요소 : IIFE 마스터하기

들어가기 전에 이 포스팅은 https://medium.com/@vvkchandra/essential-javascript-mastering-immediately-invoked-function-expressions-67791338ddc6 에 있는 포스팅들을 번역한 것입니다. 오역이나 의역이 있을 수 있습니다. 지

velog.io

 

 

클로져와 같이 쓰기 좋다고 하는데.. 클로져에 관해서는 조금 더 공부해보고 같이 정리해야겠다.

뭔가 혼자 이해하기로는.. 약간 작은 Class같은 느낌이었다. 안에 return하는게 함수라 method들을 잘 사용할 수 있는 느낌..

 

댓글