티스토리 뷰

자바스크립트에서 함수는 특별한 객체 타입이다. 이번 글에서는 자바스크립트의 함수에 대해 알아본다.

함수 정의

자바스크립트의 함수를 정의 하는 방법은 3가지가 있다.

  • 함수 선언문 (Function Statement)
  • 함수 표현식 (Function Expression)
  • Function() 생성자 함수 이용

함수 선언문 (Function Statement)

함수 선언문은 function 키워드를 이용하여 함수를 정의하는 방식이다.

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

console.log(add(3, 4)); // 7

C나 자바의 함수 선언과 달리 매개변수에 타입을 지정해주지 않는다.

함수 표현식 (Function Expression)

자바스크립트의 함수는 일급 객체라서 변수에 할당할 수 있다. 함수 표현식은 생성된 함수를 변수에 할당하는 방식을 말한다.

const addFunc = function(x, y) {
    return x + y;
}

console.log(addFunc(3, 4)); // 7

위 코드에서 함수를 정의할 때 함수 이름이 존재하지 않는 것을 볼 수 있다. 이렇게 이름 없이 정의한 함수를 익명 함수라고 하고, 이것을 변수에 할당하는 방식을 익명 함수 표현식이라고 한다. 반대로 이름이 포함된 함수 표현식은 기명 함수 표현식이라고 한다.

const addFunc = function add(x, y) {
    return x + y;
}

console.log(addFunc(3, 4)); // 7
console.log(add(5, 6)); // Uncaught ReferenceError: add is not defined

위 코드처럼 기명 함수 표현식으로 작성된 함수는 외부에서 접근이 불가하다. 대신 기명 함수를 이용하면 재귀함수 호출이 가능하다.

const factorialFunc = function factorial(n) {
    if (n <= 1) {
        return 1;
    }

    return n * factorial(n - 1);
}

console.log(factorialFunc(5)); // 120

Function 함수 생성자 이용

Function 함수 생성자로도 함수를 생성할 수 있다. 사용할 일은 없다고 봐도 되는데, 알아만 두자.

const addFunc = new Function('x', 'y', 'return x + y');
console.log(addFunc(3, 4)); // 7

함수 호이스팅

위에서 함수를 정의하는 방법에 대해 적어놨다. 자바스크립트의 함수 범위는 정의 방법에 따라 조금씩 다른데, 함수 선언문과 관련된 함수 호이스팅이라는 개념이 있다.

  • 함수 호이스팅: 함수 선언문으로 정의한 함수의 유효 범위는 코드의 맨 처음부터 시작한다.

코드를 통해 살펴보자.

console.log(add(3, 4)); // 7

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

console.log(add(5, 6)); // 11

위와 같이 함수를 정의하기 전에 호출해도 정상적으로 호출되는 것을 볼 수 있다.

함수 표현식으로 선언한 함수는 호이스팅이 일어나지 않는다.

console.log(addFunc(3, 4)); // Uncaught ReferenceError: addFunc is not defined

const addFunc = function(x, y) {
    return x + y;
}

console.log(addFunc(5, 6)); // 11

이렇게 함수의 호이스팅이 일어나는 이유는 변수 생성과 초기화가 분리돼서 일어나기 때문이다. 이것은 나중에 자세히 알아보자.

함수 프로퍼티

자바스크립트에선 함수도 객체다. 따라서 프로퍼티를 가지고 있다. 아래 그림 1을 보면 다양한 프로퍼티가 존재하는 것을 볼 수 있다.

 

[그림 1] 함수 프로퍼티

caller 프로퍼티는 자신을 호출한 함수를 나타낸다.

function callee() {
    console.log(callee.caller);
}

function caller() {
    callee();
}

caller(); // f caller() { callee(); }

arguments 프로퍼티는 함수를 호출할 때 전달된 인자값들을 나타낸다.

function sum() {
    let result = 0;

    for (let i = 0; i < arguments.length; i++) {
        result += arguments[i];
    }

    return result;
}

console.log(sum(1, 2, 3, 4)); // 10

위 코드를 보면 자바스크립트는 함수에 정의와 다르게 인자 개수를 넣어 호출해도 오류가 나지 않는다는 것을 알 수 있다. 인자 개수를 초과해도 arguments 프로퍼티에는 입력한 인자가 제대로 들어감을 알 수 있다.

그렇다면 정의된 함수와 다른 개수의 인자로 호출했을 때 인자에는 어떤 값이 들어갈까?

let argumentTestFunc = function(x, y) {
    console.log(arguments);
    console.log(x);
    console.log(y);
}

argumentTestFunc(1); // [1], 1, undefined
argumentTestFunc(1, 2, 3); // [1, 2, 3], 1, 2

위 코드처럼 테스트 해보니 입력되지 않은 인자는 undefined, 초과된 인자는 무시됨을 알 수 있다.

 

length 프로퍼티는 정의된 함수의 인자 개수를 나타낸다.

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

console.log(add.length); // 2

특이한 점은 [[Prototype]] 프로퍼티 외에 prototype 프로퍼티가 하나 더 존재하는데, 이는 프로토타입 체이닝을 공부할 때 자세히 보도록 하자.

 

'프로그래밍 > Javascript' 카테고리의 다른 글

자바스크립트 클로저  (0) 2019.11.12
자바스크립트의 실행 컨텍스트  (0) 2019.11.08
프로토타입 체이닝  (0) 2019.11.07
자바스크립트 this  (0) 2019.11.07
자바스크립트 함수  (0) 2019.11.06
자바스크립트 데이터 타입  (0) 2019.11.06
댓글
댓글쓰기 폼