본문으로 바로가기

Argument Object

호출하는 함수의 파라미터에 test(5, true,'str')와 같이 세 개의 파라미터를 넘겨주고 호출을 받는 함수의 파라미터에 받는 이름을 작성하지 않더라도 세 개의 파라미터 값을 사용할 수 있다.





이렇게 호출한 함수의 파라미터 값을 호출받은 함수에서 파라미터 값을 저장해 두고 있는데, 호출한 함수의 파라미터 값을 저장해 두는 곳이 arguments 객체이다.

호출받은 함수에서 arguments 객체에 접근하기 위해서는 오브젝트 이름이 필요하며 arguments가 그 이름이다. 

즉, arguments 객체에 호출한 함수의 파라미터 값이 순서에 따라 저장되며 호출하는 함수에서 파라미터를 지정하지 않더라도 arguments 객체가 생성되고 파라미터가 없으면  빈 값이 저장되지만 값이 없는 것 자체가 값이다.


다시 말해서, arguments 객체는 함수를 호출할 때 넘긴 인자들이 배열 형태로 저장된 객체를 의미한다. 


특이한 점은 이 객체가 배열형태로 저장되지만 실제 배열이 아닌 유사배열객체라는 점이다.


다음의 코드를 살펴보자.

JavaScript
// 호출받는 함수에 파라미터를 지정하지 않았음에도 argumets 객체를 통해서 파라미터 값을 처리
function arg() {
    if( arguments[0] !== undefined && arguments[1] !== undefined ) {
        return arguments[0] + arguments[1];
    }
    return undefined;
}

console.log(arg(4,5)); // 파라미터 값을 넘겨줌


예제 코드처럼 파라미터에 이름을 지정하지 않더라도 호출한 함수에서 넘겨 준 파라미터 값을 사용할 수는 있지만 반드시 좋은 것만은 아니다. 

호출받는 함수의 파라미터에 이름을 지정해 주면 코드의 가독성이 높아지지만 그렇지 못하다면 파라미터의 역할을 가늠하기 어려운 경우가 생길 수 있다.

그렇기 때문에 arguments 객체의 사용은 명시적인 파라미터 지정과 함께 예외,추가적인 사항이 발생할 경우에 사용하는 것이 좋다고 할 수 있다


아래 코드와 같습니다.

JavaScript
var getPrice = function(qty, price) {
    var amount;
    if(qty !== undefined && price !== undefined) {
        amount = qty * price;
        if (arguments[2] !== undefined) {
            amount = amount - arguments[2];
        }
    }
    return amount;
};

console.log(getPrice(50, 100, 200));



다음으로 arguments 객체의 length프로퍼티에 대해 알아보자.

대부분의 자바스크립트 객체는 length 프로퍼티를 가지고 있으며 객체에 따라 length프로퍼티의 용도는 다르다. 

 함수(Function) 객체의 lenth 프로퍼티 값은 호출받는 함수의 파라미터 이름 수를 나타내며 arguments 객체에도 length 프로퍼티가 있으며 호출한 함수에서 넘겨준 파라미터 수를 나타낸다.



다음의 코드를 살펴보자.

JavaScript
var lengthProp = function(one) {
    // 호출하는 함수 기준으로 arguments의 length 프로퍼티가 출력
    console.log('arguments : ' + arguments.length);
};

// 호출받는 함수기준으로 함수의 length 프로퍼티가 출력
console.log('lengthProp 파라미터 수 : ' + lengthProp.length);

// 함수 호출함
lengthProp(1,2,3);
lengthProp([4,5], 6);



이렇게 arguments에는 length 프로퍼티가 있으며 또 다른 프로퍼티가 있는데 arguments 객체의 구조에 대해 좀더 살펴보도록 하자. 

위의 코드를 보면 argument[0]으로 첫 번째 파라미터에 지정한 값을 가져올 수 있었으며 argumets 객체의 값을 인덱스([0])로 추출할 수 있기 때문에 arguments 객체를 배열로 오해할 소지가 있다. 

하지만 arguments 객체는 배열이 아니가 {name : value} 형태의 객체를 의미하기 때문에 배열이 아니다. 

그리고 객체의 형태이기 때문에 for-in문을 통해 arguments 객체의 값을 얻어올 수가 있다.



다음의 argumets 객체를 구성하는 프로퍼티를 살펴보자.


JavaScript
function get(one) {
    var args = arguments;
    // arguments 객체의 프로퍼티를 보기위해 의도적으로 args에 참조
    console.dir(args)
}

get(1,2);


콘솔창에 출력된 결과를 보면 Arguments[2]가 나타나는데 여기서 [2]값은 인덱스를 가리키는 것이 아니라 호출한 함수의 파라미터 수를 나타낸다. 

여기선 get(1,2)형태로 2개의 파라미터를 넘겨주고 있으므로 arguments[2]가 출력된 것이고, 0 : 1과 0 : 2는 객체의 형태인 {0:1, 1:2}로 객체에 저장된 형태인 것이다. 


다음으로 callee를 볼 수 있는데 callee는 현재 실행중인 함수를 가리킨다. 

위의 코드에서는 함수 선언문으로 작성되었기 때문에 get이란 함수 이름이 나타나지만 함수 표현식으로 작성된 코드라면 함수 이름이 나타나지 않을 것이다. 

이는 이름이 있는 함수는 이름으로 함수를 호출할 수 있지만 이름없는 함수는 호출할 수 없다는 의미이기도 하다. 

하지만 callee 프로퍼티를 이용하여 함수 표현식의 형태인 함수를 호출할 수 있다. 

callee 프로퍼티가 현재 실행중인 함수를 참조하므로 함수 안에서 callee 프로퍼티를 사용해서 자신을 호출할 수가 있다. 

이는 함수안에서 자신을 호출하는 것으로 재귀함수라고 하는데 재귀함수는 다음에 다루도록 해보겠다. 

그리고 마지막으로 caller 프로퍼티가 있는데 해당 코드에서는 표시되지 않았지만 caller프로퍼티는 호출한 함수를 반환하는 프로퍼티이다.



callee, caller 프로퍼티는 ES5"use strict" 모드에서는 지원하지 않는 프로퍼티이다.

필요없는 프로퍼티로 향후 없어질 프로퍼티인데 아직 strict 모드가 아닌 곳에서 지원해 주는 이유는 과거 버전의 호환서을 위한 것으로 에러가 발생하지 않도록 하기 위한 최소의 조치이다.





Jaehee's WebClub