Woowa Techcourse/Missions

Javascript IIFE(Immediately Invoked Function Expression)

mingule 2021. 3. 10. 00: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들을 잘 사용할 수 있는 느낌..