2018년 2월 11일 02:02

자바스크립트 즉시실행함수

소괄호 () 가 의미하는 바가 무엇인지 알아보고, 즉시실행함수(IIFE)가 무엇인지 알아보도록한다.

함수 선언과 표현

먼저 함수 선언과 표현에대한 차이점을 알아보도록 한다.

함수선언 (Function Declarations)

function name(parameter) {
  statements
}

name : 함수이름
parameter : 함수의 인자이며 255개까지 인자를 가질 수 있습니다
statements : 함수의 본문을 기술합니다

함수의 선언은 이름을 가지며 선언시 자동으로 호이스팅(hoisting) 됩니다.

foo()

function foo() {
  console.log('hello')
}
// "hello"

함수 선언을 뒤에 했음에도 불구하고 foo() 호출시에 정상적으로 작동

함수표현 (Function Expressions)

var variable = function name(parameter) {
  statements
}

variable : 함수를 담을 변수
name : 함수이름이며 생략가능
parameter : 함수의 인자이며 255개까지 인자를 가질 수 있습니다
statements : 함수의 본문 기술

함수를 변수에 할당을 시키면 함수표현이 된다. 변수 선언과 같음
자동으로 호이스팅이 되지 않으며, 인터프리터가 라인에 도달해야 실행 가능하다

foo()

var foo = function() {
  console.log('hello')
}

foo()
/*
Uncaught TypeError: foo is not a function
"hello"
*/

즉시실행함수(IIFE)

MDN문서 에 보면 함수표현식만이 즉시실행 가능하다고 적혀있다. 선언과 동시에 즉시 실행이 가능하게 하려면, 선언을 표현식으로 바꿔야한다.

선언을 표현식으로 바꾸는 방법은 소괄호로 감싸는 방법이다.

foo = function() {
  console.log('foo')
} // 함수선언을 함수 표현식으로 표현
foo() // "foo"

다음은 선언과 동시에 사용되는 방법이다.

;(foo = function() {
  console.log('foo')
})() // "foo"

익명함수 표현식은 다음과 같이 표현한다

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

소괄호안에 익명의 함수를 기술하면, 소괄호의 시작부분부터 종결부분까지 전체가 평가된 후 반환 된다. 결국 반환값은 자기 자신이 되어버린다

위의 코드에서 실제로 반환된 값은 익명함수 전체이다. 반환된 익명함수 전체를 실행시키기 위해 괄호를 추가했다. 추가적으로 이 익명함수의 반환값은 무엇일까?

var a = (function() {
  console.log('hello')
})()
console.log(a)
//console.log(a());

/* 출력결과
hello
undefined

마지막 주석문은 변수 a에는 익명함수가 아닌 익명함수의 반환값인
undefined 이므로 error 이다.
*/

즉시실행함수 (IIFE) 를 쓰는이유는?

전역변수(global scope) 의 선언을 막기위해

IIFE 내부에 선언된 변수들의 범위(scope)는 익명함수내로 한정이 되기 때문에 중복선언문제가 해결된다.

var foo = 'bye'

;(function() {
  var foo = 'hello'
  console.log(foo) // "hello"
})()

console.log(foo) // "bye"

똑같은 변수 foo임에도 불구하고 익명함수를 통해 중복문제를 해결했다.

클로저에서의 값의 중복 해결

클로저는 외부함수의 변수에대한 참조를 기억한다. 흔한 루프문이다.

for (var i = 0; i < 3; i++) {
  setTimeout(() => {
    console.log(i)
  }, 1000)
}
/*출력값
3
3
3
*/

i 를 참조하지만 i는 전역으로 선언이 되어있기 때문에 전역 i는 마지막 값인 3이 된다. 그래서 3이 세번 찍힌다.

그렇다면 for문이 돌때 각각의 환경을 만들어주어야한다.
이 때 IIFE를 쓰면 된다.

for (var i = 0; i < 3; i++) {
  ;(function(x) {
    setTimeout(function() {
      console.log(x)
    }, 1000)
  })(i)
}
/*출력값
0
1
2
*/

for문이 돌때마다 즉시실행함수에 i값이 parameter로 전달된다. 그리고 그 값을 x에 저장한다.
함수각각의 환경이 다르므로 각자의 값들을 기억할 수 있는것이다.

©2022 heecheolman

Built with Gatsby