호다닥

Javascript : 도대체 IIFE가 뭐야? 본문

Javascript

Javascript : 도대체 IIFE가 뭐야?

3jun 2018. 7. 26. 15:48

JavaScript: What the heck is an Immediately-Invoked Function Expression?

 

출처 : codeburst.io, Brandon Morelli

해당 내용은 Brandon Morelli의 article을 개인적으로 번역한 내용이며, 잘못 번역된 부분이 있을 수 있습니다. 원문은 위에 적힌 주소에서 확인하실 수 있습니다.

 

 

 

Function Declaration vs. Function Expression

함수 선언식 vs 함수 표현식

 

IIFE가 얼마나 유용한지 배우기에 앞서 우리는 함수 선언식과 표현식이 어떤 것들인지 이해해야한다. 

우선 전형적인 함수 선언식에 대해 배워볼 것이다. 

**FUNCTION DECLARATION**
function doSomething(){
  // ...do something...
};

 위 예제코드는 꽤나 기본적인 구조를 취하고 있다. function keyword 뒤에는 함수명인 doSomething이 있고 ( ) 와 { } 가 차례대로 위치한다.

 함수를 만드는 또 다른 방법인 함수 표현식은 아래 예제와 같은 형태를 가지고 있다. 

**FUNCTION EXPRESSION**
var doSomething = function(){
  // ...do something...
};

시각적으로 봤을 때 선언식과 표현식의 차이는 매우 근소하다. 그리고 사실 우리는 아직까지 이 함수들을 동일한 방법으로 호출할 것이다. ─ 그리고 함수의 이름 뒤에 괄호를 사용하여 호출할 것이다. 여기서는 doSomthing( ); .

 

여기서 요점은 무척 복잡하다. 자바스크립트를 파싱하면 function keyword는 우리가 명확하게 그렇지 않다고 말해주지 않는 이상은 보통 선언식을 이용해서 쓰여졌다고 간주된다.

 

이 특징은 IIFE의 문법을 이해하는데 매우 중요하다. 

 

 

 

Immediately-Invoked Function Expression Syntax

아래 예제코드는 IIFE함수이다. 보시다시피 괄호에 감싸져있고, 끝에 두번째 괄호가 있다는 것을 제외하면 기본적인 함수 선언식과 매우 유사함을 알 수 있다.

(function(){
  // ...do something...
})();

 

한번에 IIFE의 두 가지 특성에 대해 알아볼 것이다. 우선 우리는 enclosing 괄호에 대해 알아볼 것이다. ( 아래코드에서 파랑색으로 보이는 부분)

앞서서 우리는 자바스크립트는 함수 keyword를 만나면 보통 그 함수가 선언식으로 만들어졌다고 인식한다고 학습했다. 앞에서 언급했다시피 이 특징은 매우 중요하다. 만약 우리가 enclosing 괄호 없이 IIFE 함수를 만들려고 한다면 자바스크립트는 우리가 함수 선언식을 실행시키려하지만 실수로 함수의 이름을 생략했다고 받아들일 것이고 아래와 같은 문법 에러를 출력한다. 

function(){ /*...do Something...*/ }(); 
// SyntaxError: Unexpected token (

 

위에서 언급했듯이 자바스크립트는 너가 함수 선언식을 만들고자 했다고 생각할 것이다. 

// Did you mean to type this?
function doSomething(){ /*...do Something...*/ }();

 

그러나 그것은 우리가 원하는 것이 아니다. 다행스럽게도 함수 표현식을 정상적으로 기능하게 할 수 있다. 

 

우리의 함수를 괄호로 감쌈으로서 우리는 파서에게 함수 표현식으로 파싱하라고 명령할 수 있다. (함수 선언식이 아니라)

이로써 우리의 코드는 오류 없이 compile 되게 된다. 

 

이제 우리는 IIFE에서 첫번째 괄호가 어떤 역할을 하는지 알게되었다. 그렇다면 IIFE에서 두번째 괄호는 무엇일까? (아래 예제 코드의 빨간색 괄호)

괄호는 함수들을 호출하는데 사용된다. 그래서 아래의 예제 코드를 보면 함수 선언식 바로 뒤에 있는 한쌍의 괄호는 함수를 즉시 호출할 것이다. 

 

그럼 무슨일이 일어날까? 크롬 개발자 도구를 열고 아래의 함수 선언식 예제코드를 콘솔창에 실행시켜보자. 

function speak(){
    console.log('hello');
};

이제 speak () 를 콘솔창에 입력하기만 하면 함수를 호출할 수 있게 되었다. 그럼 hello라는 결과값을 return받게 될 것이다. 

그러나 speak에서 괄호를 생략하게 된다면 어떻게 될까?

speak();
// 'hello'
speak;
//  function speak(){
//    console.log('hello');
//  }

괄호를 생략하게 되면 함수는 결코 호출되지 않는다. 그리고 함수 정의가 대신 return된다. 

 

이로써 함수 표현식 끝에 괄호를 포함함으로써 IIFE 함수가 즉시 호출될 것이라는게 명확해졌다. 

 

 

 

The Why.

이제 우리는 IIFE가 어떤 기능을 하고 코드가 어떻게 동작하는지에 대해 학습했다. : 함수표현식을 만들고 그 함수를 즉시 실행한다. 이제 우리는 가장 중요한 질문인 Why? 에 대해 답할 수 있다. 

 

왜 우리는 함수를 만들고 그 다음에 바로 함수를 호출하는 방법 대신 IIFE 함수를 사용하는가?

 

Privacy.    보안때문이다.

 

자바스크립트에서 변수들은 그들을 포함하고 있는 함수에 의해 scope로 묶인다. 이것은 함수 외부에 접근할 수 없음을 의미한다. 아래에 간단한 예제가 있다.

(function(){
  var superSecret = 195;
})()
console.log(superSecret);
//  Uncaught ReferenceError: superSecret is not defined

우리는 IIFE 함수 외부에서 superSecret 변수에 접근할 수 없다. IIFE함수 내부의 모든 코드들은 해당 함수의 private scope에 묶이게 된다. 

 

그러나 어떤 함수명으로 함수를 만들고 호출한다면 어떻게 될까? 같은 결과를 만들어낼 수 있을까?

 

그렇다. 하지만 함수명을 가진 함수를 만든다면 전역 name 스코프를 오염시킨다. 이것은 함수명을 가진 함수가 전역스코프에 접근할 수 있음을 의미한다. 이러한 이유로 이 함수들은 불필요한 상황에서 출력될 수 있다. 

IIFE함수는 함수명이 없기 때문에 이후에 실수로 호출될 일이 없기 때문에 잠재적인 보안 이슈를 피할 수 있다. 

 

 

Comments