티스토리 뷰


JS


함수(Function)


1. 함수 선언(Function declaration 혹은 Function statement)

함수 선언(Function declaration)을 MDS에서 밑에와 같이 정의 하였습니다.


문법

function name([param,[, param,[..., param]]]) {
   [statements]
}

name

The function name.


param

The name of an argument to be passed to the function. Maximum number of arguments varies in different engines.


statements

The statements which comprise the body of the function.


함수 선언 호이스팅(Function declaration hoisting)

함수 선언은 호이스팅이 됩니다. ([JavaScript] 유효범위(Scope)와 호이스팅(Hoisting) 참고)

hoisted(); // logs "foo"

function hoisted() {
  console.log("foo");
}

함수 선언 호이스팅함수 선언 호이스팅


알게 모르게 저희는 함수 선언 호이스팅을 사용하고 있었습니다. 함수는 호출 먼저 하고, 함수 정의는 나중에 정의하는..


하지만, 다음으로 이야기할 함수 표현은 호이스팅이 되지 않습니다.

notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function() {
   console.log("bar");
};

함수 표현은 호이스팅이 되지 않는다함수 표현은 호이스팅이 되지 않는다


호이스팅된 코드를 보면 이해하기 쉽습니다.

var notHoisted;

notHoisted(); // TypeError: notHoisted is not a function

notHoisted = function() {
   console.log("bar");
};

정의 되어 있지 않는 변수를 사용하려 하여 에러가 출력되는 것은 당연합니다.



2. 함수 표현(Function expression)

함수 표현(Function expression)을 MDS에서 밑에와 같이 정의 하였습니다.


문법

function [name]([param1[, param2[, ..., paramN]]]) {
   statements
}

name

The function name. Can be omitted, in which case the function is anonymous. The name is only local to the function body.


paramN

The name of an argument to be passed to the function.


statements

The statements which comprise the body of the function.


익명 함수 표현 (Anonymous function expression)

익명 함수 표현의 예를 들어보겠습니다.

var x = function(y) {
   return y * y;
};
console.log(x(2)); // 4

익명 함수 표현익명 함수 표현


기명 함수 표현 (Named function expression)

기명 함수 표현의 예를 들어보겠습니다.

var x = function square(y) {
   return y * y;
};
console.log(x(2)); // 4

기명 함수 표현기명 함수 표현


여기서 저는 궁금한 점이 하나 생겼습니다. 기명 함수 표현으로 함수의 이름이 있다면 함수 이름으로 함수 실행이 가능 할까..?

var x = function square(y) {
   return y * y;
};
square(2);

기명 함수 표현함수이름으로 함수 실행이 되지 않는다


안됩니다.... 그렇다면, 왜 기명 함수 표현을 사용하는 걸까요?


One of the benefit of creating a named function expression is that in case we encounted an error,

the stack trace will contain the name of the function, making it easier to find the origin of the error.


MDS에서는, 장점 하나는 에러가 발생 했을 때, stack trace가 함수의 이름을 포함하여 출력하기 때문에 에러를 찾기 쉬운 것이 기명 함수 표현의 장점이라고 이야기 함니다.


MDS에서 함수 정의에 몇가지 방법을 더 이야기 하는데, 이번 포스팅에서 2가지만 이야기하겠습니다.

(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions 참고)



즉시 실행 함수 (Immediately-invoked function expression)



즉시 실행 함수의 기본 형태는 아래와 같습니다.

(function () {
    // statements
})()

함수 표현(Function expression)은 함수를 정의하고, 변수에 함수를 저장하고 실행하는 과정을 거칩니다. 하지만 즉시 실행 함수는 함수를 정의하고 바로 실행하여 이러한 과정을 거치지 않는 특징이 있습니다. 함수를 정의하자마자 바로 호출하는 것을 즉시 실행 함수라고 이해하면 편할 것 같습니다.


Immediately-invoked function expression 영어를 해석하면 즉시-호출 함수 표현 입니다. 즉시 실행 함수(IIFE)는 함수 표현(function expression)과 같이 익명 함수 표현, 기명 함수 표현으로 할 수 있습니다.



1. 즉시 실행 함수 사용법

기명 즉시 실행 함수

(function square(x) {
    console.log(x*x);
})(2);

(function square(x) {
    console.log(x*x);
}(2));

위의 두가지 예는 괄호의 위치가 조금 다를 뿐 같은 기능의 즉시 실행 함수 입니다.


익명 즉시 실행 함수

(function (x) {
    console.log(x*x);
})(2);

(function (x) {
    console.log(x*x);
}(2));


변수에 즉시 실행 함수 저장

즉시 실행 함수도 함수이기 때문에, 변수에 즉시 실행 함수 저장이 가능합니다. 예를 들어 보겠습니다.

(mySquare = function (x) {
    console.log(x*x);
})(2);
mySquare(3);

변수에 즉시 실행 함수 저장변수에 즉시 실행 함수 저장


함수를 mySquare에 저장하고 이 함수를 바로 실행하게 됩니다. mySquare는 즉시 실행 함수를 저장하고 있기 때문에 재호출이 가능하게 됩니다.


마찬가지로 즉시 실행 함수도 함수이기 때문에, 변수에 즉시 실행 함수의 리턴 값 저장도 가능합니다.

var mySquare = (function (x) {
    return x*x;
})(2);
console.log(mySquare)

변수에 즉시실행함수 리턴값 저장변수에 즉시실행함수 리턴값 저장


위의 두가지는 형태가 유사하지만 엄연히 다른 기능입니다. 괄호의 위치에 주의가 필요할 것 같습니다.



2. 즉시 실행 함수를 사용하는 이유

초기화

즉시 실행 함수는 한 번의 실행만 필요로 하는 초기화 코드 부분에 많이 사용됩니다.

그렇다면 왜 초기화 코드 부분에 많이 사용 할까요? 변수를 전역(global scope)으로 선언하는 것을 피하기 위해서 입니다. 전역에 변수를 추가하지 않아도 되기 때문에 코드 충돌 없이 구현 할 수 있어, 플러그인이나 라이브러리 등을 만들 때 많이 사용됩니다.


예를 하나 들어보겠습니다.

var initText;

(function (number) {
    var textList = ["is Odd Text", "is Even Text"];
    if (number % 2 == 0) {
        initText = textList[1];
    } else {
        initText = textList[0];
    }
})(5);

console.log(initText);
console.log(textList);

즉시실행함수 이용한 초기화즉시실행함수 이용한 초기화



전역에 textList가 저장되지 않고, initText만 초기화 된 것을 확인 할 수 있습니다. 또한 textList는 지역 변수로, 전역 변수와 충돌없이 초기화 할 수 있게 됩니다.


라이브러리 전역 변수의 충돌

jQuery나 Prototype 라이브러리는 동일한 $라는 전역 변수를 사용합니다. 만약, 이 두개의 라이브러리를 같이 사용한다면 $ 변수 충돌이 생기게 됩니다.

즉시 실행 함수를 사용하여 $ 전역 변수의 충돌을 피할 수 있습니다.

(function ($) {
    // $ 는 jQuery object
})(jQuery);

즉시 실행 함수 안에서 $는 전역변수가 아닌 jQuery object의 지역 변수가 되어, Prototype 라이브러리의 $와 충돌 없이 사용할 수 있습니다.



댓글
댓글쓰기 폼