arguments 객체

arguments 객체

arguments는 함수 내부에서 접근할 수 있는 array-like 객체로, 그 함수에 전달된 인자(arguments)의 값을 담고 있다.

출처: The arguments object - JavaScript | MDN

본문

Try it

function func1(a, b, c) {
  console.log(arguments[0]);
  // Expected output: 1

  console.log(arguments[1]);
  // Expected output: 2

  console.log(arguments[2]);
  // Expected output: 3
}

func1(1, 2, 3);

개요

참고: 현대 코드에서는 rest 파라미터를 선호해야 한다.

arguments 객체는 모든 non-arrow 함수 내에서 사용 가능한 지역 변수이다. 함수 내에서 arguments 객체를 사용해 그 함수의 인자들을 참조할 수 있다. 함수가 호출될 때 전달된 각 인자에 대한 항목을 가지며, 첫 번째 항목의 인덱스는 0이다.

예를 들어 함수에 3개의 인자가 전달되면 다음과 같이 접근할 수 있다:

arguments[0]; // first argument
arguments[1]; // second argument
arguments[2]; // third argument

arguments 객체는 공식적으로 선언된 것보다 더 많은 인자로 호출되는 가변 인자(variadic) 함수(예: Math.min())에 유용하다. 이 예제 함수는 임의 개수의 문자열 인자를 받아 가장 긴 문자열을 반환한다:

function longestString() {
  let longest = "";
  if (arguments.length === 0) {
    throw new TypeError("At least one string is required");
  }
  for (const arg of arguments) {
    if (arg.length > longest.length) {
      longest = arg;
    }
  }
  return longest;
}

arguments.length를 사용해 함수가 몇 개의 인자로 호출되었는지 셀 수 있다. 함수가 선언상 몇 개의 파라미터를 받도록 되어 있는지 세고 싶다면 그 함수의 length 속성을 검사하면 된다.

인덱스에 값 할당하기(Assigning to indices)

각 인자 인덱스는 설정하거나 다시 할당할 수도 있다:

arguments[1] = "new value";

오직 단순 파라미터(즉 rest, default, destructured 파라미터가 없는)만 가진 non-strict 함수는 파라미터의 새 값을 arguments 객체와 동기화하며, 그 반대도 마찬가지이다:

function func(a) {
  arguments[0] = 99; // updating arguments[0] also updates a
  console.log(a);
}
func(10); // 99

function func2(a) {
  a = 99; // updating a also updates arguments[0]
  console.log(arguments[0]);
}
func2(10); // 99

rest, default, destructured 파라미터가 전달된 non-strict 함수는 함수 본문에서 파라미터에 할당된 새 값을 arguments 객체와 동기화하지 않는다. 대신 복잡한 파라미터를 가진 non-strict 함수의 arguments 객체는 항상 함수가 호출될 때 전달된 값들을 반영한다.

function funcWithDefault(a = 55) {
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
funcWithDefault(10); // 10

function funcWithDefault2(a = 55) {
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
funcWithDefault2(10); // 10

// An untracked default parameter
function funcWithDefault3(a = 55) {
  console.log(arguments[0]);
  console.log(arguments.length);
}
funcWithDefault3(); // undefined; 0

이는 전달되는 파라미터의 타입과 무관하게 모든 strict 모드 함수가 보이는 동작과 동일하다. 즉 strict 모드 함수에서는 본문에서 파라미터에 새 값을 할당해도 arguments 객체에 영향을 주지 않으며, arguments 인덱스에 새 값을 할당해도 파라미터 값에 영향을 주지 않는다(함수가 단순 파라미터만 가진 경우에도 마찬가지).

참고: rest, default, destructured 파라미터를 받는 함수 정의의 본문에는 "use strict"; 지시자를 쓸 수 없다. 그렇게 하면 문법 오류가 발생한다.

arguments는 array-like 객체이다

arguments는 array-like 객체이다. 즉 argumentslength 속성과 0부터 시작하는 인덱스 속성을 가지지만, forEach()map() 같은 Array의 내장 메서드는 가지지 않는다. 다만 slice(), Array.from(), spread 문법 중 하나를 사용해 실제 Array로 변환할 수 있다.

const args = Array.prototype.slice.call(arguments);
// or
const args = Array.from(arguments);
// or
const args = [...arguments];

일반적인 사용에서는 iterable이고 length와 숫자 인덱스를 모두 가지므로 array-like 객체로 사용하는 것으로 충분하다. 예를 들어 Function.prototype.apply()는 array-like 객체를 받아들인다.

function midpoint() {
  return (
    (Math.min.apply(null, arguments) + Math.max.apply(null, arguments)) / 2
  );
}

console.log(midpoint(3, 1, 4, 1, 5)); // 3

속성(Properties)

  • arguments.callee — arguments가 속한 현재 실행 중인 함수에 대한 참조. strict 모드에서는 금지된다.
  • arguments.length — 함수에 전달된 인자의 수.
  • arguments[Symbol.iterator]()arguments의 각 인덱스에 대한 값을 담은 새 배열 반복자 객체를 반환한다.

예제

여러 문자열을 연결하는 함수 정의하기

이 예제는 여러 문자열을 연결하는 함수를 정의한다. 함수의 유일한 공식 인자는 연결할 항목들을 구분하는 문자를 담은 문자열이다.

function myConcat(separator) {
  const args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
}

이 함수에는 원하는 만큼 많은 인자를 전달할 수 있다. 각 인자를 사용해 문자열 목록을 반환한다:

myConcat(", ", "red", "orange", "blue");
// "red, orange, blue"

myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
// "elephant; giraffe; lion; cheetah"

myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
// "sage. basil. oregano. pepper. parsley"

HTML 목록을 생성하는 함수 정의하기

이 예제는 목록에 대한 HTML을 담은 문자열을 만드는 함수를 정의한다. 함수의 유일한 공식 인자는 목록이 순서 없는(bulleted) 목록이면 "u", 순서 있는(numbered) 목록이면 "o"인 문자열이다. 함수는 다음과 같이 정의된다:

function list(type) {
  let html = `<${type}l><li>`;
  const args = Array.prototype.slice.call(arguments, 1);
  html += args.join("</li><li>");
  html += `</li></${type}l>`; // end list
  return html;
}

이 함수에는 원하는 만큼 많은 인자를 전달할 수 있으며, 각 인자를 해당 타입 목록의 항목으로 추가한다. 예를 들어:

list("u", "One", "Two", "Three");
// "<ul><li>One</li><li>Two</li><li>Three</li></ul>"

arguments에 typeof 사용하기

typeof 연산자는 arguments와 함께 사용하면 'object'를 반환한다.

console.log(typeof arguments); // 'object'

개별 인자의 타입은 arguments를 인덱싱해 결정할 수 있다:

console.log(typeof arguments[0]); // returns the type of the first argument

명세(Specifications)

  • ECMAScript® 2027 Language Specification — sec-arguments-exotic-objects

브라우저 호환성

baseline 기준 2015년 7월부터 널리 사용 가능하다. 호환성 표는 JavaScript를 활성화해야 볼 수 있다.

참고 자료

  • Functions 가이드
  • Functions
  • Rest parameters

더 알아보기