탱구탱구 개발자 일기

[즉시 실행 함수]

익명 함수를 실행할 때는 아래와 같이 변수에 할당하여 그룹 연산자 ()로 실행한다.

// 기본적인 익명함수 실행
let f = function () {
    return 10;
}
f();

 

익명 함수를 정의하는 동시에 실행하는 구문. 결과는 차이가 없다.

// 즉시 실행 함수 방법 1
(function () {
    return 10;
})();

// 즉시 실행 함수 방법 2
(function() {
    return 10;
}());

// 즉시 실행 함수는 함수 선언문을 그룹 연산자 ()로 묶은 것이다
(
    function (){
        return 10;
    }()
);

그룹 연산자가 안에 있는 함수 선언문을 평가해 함숫값(함수 객체의 참조 값)으로 바꾼다. 그룹 연산자 대신 아래와 같이 사용해도 된다. 그러나 문자열을 return 하거나 로그로 찍는 건 상관없지만 아래와 같이 숫자형을 return 할 경우 의도한 결과가 나오지 않는다. 왜냐하면 표현식이 되기 때문이다.

// 그룹 연산자() 대신 +, !, ~
+function () {
    return 30;
}();

// 30

!function () {
    return 40;
}();

// false

~function () {
    return 50;
}();

// -51

즉시 실행 함수에도 인수를 넘길 수 있다.

// 인수 넘기기
(function (a, b) {
    return a + b;
})(1, 2);
// 3

즉시 실행 함수에도 익명함수와 마찬가지로 이름을 붙일 수 있다. 다만 함수 이름은 함수 내부에서만 유효하다.

// 이름 붙이기
(function fact(n) {
    if (n <= 1) {
        return 1;
    }
    return n * fact(n - 1);
})(5);

변수에도 할당 가능하므로 표현식으로도 사용 가능하다. 대신 즉시 실행 함수는 함수 결과를 return 하므로 할당된 변수를 사용할 때 변수에 따로 ()를 붙일 필요 없다.

// 표현식으로 사용
let a = (function () {
    return 10;
})();
a;

// 10

또한 즉시 실행 함수는 전역 유효 범위를 오염시키지 않는 이름 공간을 생성할 때 사용한다. 이름 공간에 대해서는 이 글을 참고하면 좋을 것 같다.

 

[함수를 이름 공간으로 활용]

 

전역 유효 범위를 오염시킨다는 것은 전역 변수나 전역 함수를 선언할 때 해당 객체들이 전역 객체의 프로퍼티로 등록되는 현상을 말한다.

function f1() {
    return 10;
};

function f1() {
    return 20;
};

window.f1();
// 20

동일한 이름의 함수가 전역 함수로 선언된다고 가정하자. 웹 브라우저에서 전역 객체는 window 객체다. 객체 안의 프로퍼티에는 동일한 식별자(key)가 중복될 수 없다. 자바스크립트 엔진이 위 코드를 실행할 때 동명의 함수 중 가장 나중에 읽힌 두 번째 f1 함수를 호이스팅하여 하나만 window 객체의 프로퍼티로 등록한다. 서로 다른 개발자가 동일한 이름으로 함수를 생성했는데 같은 프로그램 안에서 사용한다면?? 상황에 따라서는 심각한 문제가 될 수 있다.

 

자바스크립트는 기본적으로 함수 레벨 스코프를 갖기 때문에 함수 안에서 선언된 변수의 유효 범위는 함수 내부로 제한된다. 따라서 이러한 특성을 이용해 즉시 실행 함수를 사용하면 이름 공간으로 활용할 수 있다.

// 이름 공간으로 활용
var x = "global x";
(function () {
    var x = "local x";
    var y = "local y";
})();
console.log(x); // global x
console.log(y); // Uncaught ReferenceError: y is not defined
(function () {
   // 이곳에 프로그램을 작성한다.
})();

아래와 같이 작성하면 함수 내부에서 선언한 변수는 모두 지역변수이기 때문에 외부 라이브러리를 사용할 때 해당 라이브러리에서 선언한 전역 변수와 충돌하지 않는다. 즉, 전역 유효 공간을 오염시키지 않는다.

이 글을 공유합시다

facebook twitter kakaoTalk kakaostory naver band
loading