본문 바로가기

Programming/Javascript

8. Javascript 함수 호출 (1) - arguments 객체

javascript image logo

 

 

함수의 호출과 arguments 객체

기본적으로 C 등의 프로그래밍 언어에서는, 함수를 호출할 때 인자를 정확하게 할당해야 합니다. 예를 들어 함수에서 정의된 파라미터가 2개라면, 인자는 반드시 2개가 전달되어야 에러가 발생하지 않습니다. 

 

하지만, Javascript에서는 이러한 규칙이 유연하게 적용됩니다. 선언된 함수에서 필요로 하는 인자의 개수와 무관하게 함수는 나름대로의 규칙을 통해 전달된 인자를 처리하게 됩니다. 예를 들어 파라미터가 2개인데 이보다 적게 인자가 전달된다면, undefined로 처리합니다. 반대로 2개 이상의 인자가 전달된다면, 초과된 인수를 무시하고 앞의 2개 만을 처리합니다. 

 

function func(arg1, arg2){
    console.log(arg1, arg2);
}

func();
func('a');
func('a', 'b');
func('a', 'b', 'c', 'd');

/* 출력
undefined undefined
a undefined
a b
a b
*/

 

결국, 함수가 위와 같은 인자에 관련된 처리를 진행하기 위해서는 인자가 어딘가에 저장되어 전달이 되어야만 합니다. 특정 객체에 인자가 저장이 되어 있다면, 이 정보를 읽어 상황에 따라 다른 처리를 할 수 있을테니까요. 이 역할을 하는 것이 바로 arguments 객체입니다. Javascript에서는 함수를 호출할 때, 인자가 전달되는 동시에 arguments객체가 내부로 전달되는 과정을 거치게 됩니다.

 

 


 

arguments 객체 구성 요소

우선 아래와 같이 간단한 더하기 결과 출력 함수를 예시로 살펴보겠습니다. 함수를 호출하면 그에 따른 argumnets 객체를 출력하도록 선언했네요.

 

function plus(x, y) {
    console.dir(arguments);
    return x + y;
}

console.log(plus(1));
console.log(plus(1, 2));
console.log(plus(1, 2, 3));

 

arguments console result
위 코드의 실행 결과를 chrome에서 확인합니다

 

우선 결과를 살펴보겠습니다. plus(1)을 호출한 결과는 NaN이 출력되었습니다. 두 개의 인자를 받아 더하는 함수이기 때문에 당연한 결과처럼 보이지만, 앞서 설명했듯이 컴파일 에러가 발생하지 않고 실행이 정상적으로 되었습니다. 다만 결과가 NaN일 뿐이지요. plus(1, 2, 3)을 호출한 결과는 plus(1, 2)의 실행결과와 마찬가지로 3이 출력되었습니다. 초과 전달된 3을 무시해버리고 연산했다는 것을 알 수 있습니다. 

 

이제 arguments 객체 자체의 구성 요소를 살펴보도록 하겠습니다. 이 중 [[Prototype]] 객체는 살펴보았으니, 다른 3개의 요소를 알아볼 차례네요. 

 

우선 맨 위에 인덱스 넘버가 포함된 배열이 있습니다. VS Code의 콘솔 기준으로, [Arguments] { '0': 1, '1': 2 } 입니다. 이는 함수 호출 시 전달된 인자를 의미합니다. 유사 배열의 형태로 파라미터로 전달된 인자들을 저장합니다. 

 

그리고 현재 실행 중인 함수(어떤 함수를 참조하여 실행하는가?)의 참조 값을 callee 프로퍼티에서 확인할 수 있습니다. 더불어 유사 배열 객체 형태이므로, length가 존재합니다. 실제 연산 과정에서는 무시하더라도, 전달된 인자의 개수를 그대로 출력하고 있습니다. 

 

참고로 함수가 갖는 arguments 객체는 유사 배열 객체이므로, 표준 배열 메서드를 사용할 수 없습니다. 이와 관련해서는 call, apply 메서드를 설명하는 과정에서 좀 더 디테일하게 공부해 보겠습니다. 

 

 


 

이제 위에서 배운 arguments를 한 번 써먹어보도록 하겠습니다. arguments 객체와 for문을 이용하여 특정 함수에 전달된 인자를 모두 더해 리턴하는 함수를 만들어볼 생각입니다. 인자가 1개이든, 100개이든간에 무조건 더하여 출력하는 함수 말이죠.

 

function argSum() {
    var result = 0;

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

    return result;
}

console.log(argSum(1, 3, 8));
console.log(argSum(1, 3, 8, 213, 324, 453));

 

arguments에 전달된 배열 요소들을 모두 더해주는 식을 만들어 보았습니다. 다만, 여기서 주의할 것이 있습니다. for문 조건식 부분에서 i < arguments.length; 를 i <= arguments.length; 로 작성할 경우에는 NaN이 출력됩니다. 예를 들어 인자를 3개를 넣었을 경우 [0] ~ [3] 인덱스를 연산하게 됩니다. 하지만 이 때 arguments [3]에는 아무 원소가 없는 undefined가 됩니다. 그러므로 이를 연산하게 되면 NaN이 출력되는 것입니다. 맨 처음, 인자가 없는 경우 NaN이 출력되는 예시와 마찬가지의 상황입니다.