본문 바로가기

Programming/Javascript

7. Javascript 함수 (1) - 함수 선언 2

javascript logo image

 

함수 표현식에서의 기명 함수 사용

앞서 함수 표현식에서의 익명함수에서 설명했듯이, 함수 표현식에서 사용되는 함수명은 코드 외부에서는 사용이 불가하기 때문에 실제로 사용되는 일은 많지 않습니다. 대부분 함수 변수를 통해 실행하게 됩니다. 단, 기명 함수를 대입하여 사용하는 경우가 있는데, 대표적인 사용 케이스가 재귀적 호출이 필요한 경우입니다. 

 

즉, 함수 변수에 대입한 함수의 선언문 내부에서 함수 자기 자신을 다시 한 번 호출해야 하는 경우가 있을 때 해당 기명 함수를 사용하게 되는 것 입니다. 아래 대표적인 예제인 팩토리얼 함수 구현을 살펴보겠습니다.

 

var factorialVar = function factorial(n) {
    if( n <= 1 ){
        return 1;
    } 
    return n * factorial(n-1);
};

console.log(factorialVar(3));
// console.log(factorial(3));

 

위에서 팩토리얼을 함수로 구현해 보았습니다. 기명 함수 factorial(n)을 재귀적으로 사용해야 하는 코드를 사용해야 하기 때문에 함수 변수 factorialVar가 참조하는 기명 함수 factorial(n)을 선언해두었습니다.

 

맨 아래의 두 라인에서 실행 결과를 보면 함수 변수 factorialVar를 통해 실행한 경우 정상적으로 값이 6으로 출력 되지만 factorial로 실행하였을 경우에는[ReferenceError: factorial is not defined]가 출력됩니다. 즉, factorial 이라는 함수가 선언되지 않았다는 의미입니다. 말했듯 기명 함수는 함수 코드 내부에서는 사용이 가능하지만, 외부에서는 사용이 불가 하나는 점을 다시 확인했습니다. 

 

 


 

Function( ) 생성자를 이용한 함수 선언

Javascript 함수 역시 Function( )이라는 생성자 함수를 통해 생성된 하나의 객체라고 볼 수 있습니다. 기본적으로 함수 리터럴 방식으로 선언문 / 표현식을 통해 함수가 선언되지만, Function( ) 생성자 함수가 있다는 사실도 참고삼아 기억해 두세요.

 

var plus = new Function('x', 'y', 'return x + y');
console.log(plus(22, 589));

 

new Function 형태로 생성할 때 인자는 new Function(arg1, arg2, ... ,argN, functionBody) 형태가 됩니다. 인자를 나열하고 함수 호출 시 실행된 코드를 문자열로 전달하면 기존의 함수와 동일한 방식으로 실행할 수 있습니다.

 

 

 


 

 

함수 호이스팅

Javascript에서는 함수와 관련하여 "반드시 함수는 사용하기 전에 선언해야 한다."는 규칙을 갖는다. 당연한 이야기처럼 들릴지 모르지만, 코드가 복잡해지면 선언과 실행이라는 순서가 뒤섞이는 경우도 종종 있으므로 주의해야 합니다. 

 

함수 표현식에서 이 규칙을 잘 확인해 볼 수 있습니다. 아래 plus 함수의 실행 예제를 살펴봅시다.

 

 

console.log(plus(5, 32));

var plus = function(x, y){
    return x + y;
};

console.log(plus(99, 1));

 

위의 예제를 실행하면, (당연하겠지만) 컴파일 에러가 발생합니다. [TypeError: plus is not a function], 즉 첫 라인의 plus는 함수로 선언되지 않은 상태이기 때문에 실행이 불가능한 것이죠. 

 

하지만, 이와 달리 함수 선언문의 경우 조금 다른 결과를 보여줍니다. 

 

 

console.log(plus(5, 32));

function plus(x, y){
    return x + y;
}

console.log(plus(99, 1));

 

함수 선언문으로 작성된 위의 코드는 놀랍게도 37, 100이라는 결과를 정상적으로 출력합니다. 이를 통해 '함수 선언문'으로 작성된 함수의 유효 범위는 코드의 처음부터 시작된다는 것을 확인할 수 있습니다. 이를 함수 호이스팅(Function Hoisting)이라고 칭합니다. 

 

호이스팅이 가능한 부분에 대해서는 추후 함수변수 생성 등을 배우며 자세히 다루어 볼 텐데요, 우선은 이런 현상이 발생 가능하다는 것을 이해만 해두고 있어도 충분합니다. 특히 "선언 후 실행"이라는 기본 원칙만 기억하고 이를 코드 작성 시에 반영하면 됩니다. 이 호이스팅 때문에 가급적 선언문 보다는 함수 표현식을 쓰라는 권고가 있으니, 참고해 두세요.