
점 세개 (...)로 니머지 매개변수를 나타낸다.
자바스크립트에서 함수에 넘겨주는 인수의 개수에는 제한이 없다. 인수의 개수를 정해놓고 함수를 만들어도, 실제 함수를 호출할 때 정확하게 인수의 개수를 맞출 필요가 없다. 아래 코드처럼 showName() 함수를 만들 때 정해놓은 인수의 개수가 하나임에도, 여러 개의 인수를 넘겨주거나 아애 인수를 넘겨주지 않음에도 오류가 발생하진 않는다.
function showName(name) {
console.log(name);
}
showName('Mike'); // 'Mike'
showName('Mike', 'Tom'); // 'Mike'
showName(); // undefined
📝 ES6 문법이 사용 가능한 환경이라면 가급적 arguments보다 나머지 매개변수 사용을 권장한다.
Array 형태의 객체로 함수로 넘어온 모든 인수에 접근한다. 함수 내에서만 이용 가능한 지역 변수이며, length 속성을 가진다. 그리고, arguments 객체는 함수에 전달된 인수들을 인덱스를 통해 접근할 수 있다. arguments는 배열처럼 리스트 형태로 데이터를 저장하지만, 배열의 내장 메서드(forEach, map)는 없다. arguments는 배열이 아니다.
function showName(name) {
console.log(arguments.length);
console.log(arguments[0]);
console.log(arguments[1]);
}
showName('Mike', 'Tom');
// 2
// 'Mike'
// 'Tom'
arguments 객체는 따로 선언하지 않아도 사용할 수 있는 자바스크립트 내장 객체이다. 함수 호출할 때, JS 엔진이 자동으로 arguments 객체를 생성한다.
정해지지 않은 개수의 인수를 배열로 나타낼수 있게 한다.
function showName(...names) {
console.log(names);
}
showName(); // []
showName('Mike'); // ['Mike']
showName('Mike', 'Tom'); // ['Mike', 'Tom']
인수로 넘겨받은 값을 모두 더해서 값을 출력해주는 예시이다. forEach() 배열 메서드를 사용하여 총합을 구할 수 있다.
function add(...numbers) {
let result = 0;
numbers.forEach((num) => (result += num));
console.log(result);
}
add(1,2,3) // 6
reduce() 배열 메서드를 사용해서 총합을 구할 수도 있다.
function add(...numbers) {
let result = numbers.reduce((prev, cur) => prev += cur);
console.log(result);
};
add(1,2,3); // 6
아래 코드는 user 객체를 만들어 주는 생성자 함수를 만드는 좀 더 실용적인 예시이다. 나머지 매개변수는 항상 매개변수들 중에서 제일 마지막에 있어야 한다.
function User(name, age, ...skills) {
this.name = name;
this.age = age;
this.skills = skills;
}
const user1 = new User("Mike", 30, "html", "css");
const user2 = new User("Tom", 20, "JS", "React");
console.log(user1); // {name: "Mike", age: 30, skills: ["html", "css"]}
console.log(user2); // {name: "Tom", age: 20, skills: ["JS", "React"]}
...arr1은 arr1 배열의 요소를 풀어서 쓴 것이다. 다시말해, ...arr1은 배열의 모든 요소 1,2,3이라 할 수 있다.
...arr2는 arr2 배열의 요소를 풀어서 쓴 것이다. 마찬가지로 ...arr2는 배열의 모든 요소 4,5,6이라 할 수 있다.
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let result = [...arr1, ...arr2];
let result2 = [0, ...arr1, ...arr2, 7, 8];
console.log(result); // [1, 2, 3, 4, 5, 6]
console.log(result); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
arr1 배열을 [4,5,6,1,2,3]으로 바꾸려 한다. 이를 위해선 어떻게 코드를 짜야할까?
배열 전개 구문을 사용하지 않는다면 코드가 아래처럼 코드가 길어진다. arr2.reverse().forEach()는 arr2.reverse()가 먼저 실행되어 역순으로 정렬된 배열을 반환한다. 그 후, 해당 배열에 대해 arr.forEach() 메서드가 실행된다.
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
arr2.reverse().forEach((num) => {
arr1.unshift(num)
});
console.log(arr1); // [4, 5, 6, 1, 2, 3]
반면, 배열 전개 구문을 사용하면 이렇게 짧은 코드로 문제를 해결 가능하다.
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
arr1 = [...arr2, ...arr1];
console.log(arr1); // [4,5,6,1,2,3]
기존에는 arr.push(), arr.splice(), arr.concat() 등을 사용해서 배열에 요소를 넣고, 빼고, 병합하는 작업이 번거로웠다. 하지만, 전개 구문을 사용해 위 작업을 쉽게 할 수 있다. 아래 코드는 전개구문을 사용해서 배열을 복제한다.
let arr = [1,2,3];
let arr2 = [...arr]; // [1, 2, 3]
객체도 마찬가지로 전개 구문을 사용할 수 있다. 아래 코드는 전개 구문을 사용하여 user 객체를 user2에 복제했다. ...user는 user 객체의 프로퍼티들을 풀어서 쓴 것과 같으며, name: 'Mike', age: 30이라 말할수 있다. Object.assign() 메서드를 사용하지 않고도 객체를 복제할 수 있다.
let user = {name: 'Mike', age: 30};
let user2 = {...user}; // {name: 'Mike', age: 30};
user2.name = "Tom";
console.log(user2.name); // 'Tom'
console.log(user2.age); // 30
객체 전개 구문을 사용하지 않고 user 객체에 프로퍼티를 추가하려면, Object.assign() 메서드를 사용하고, 일일이 각 요소들을 push() 해주어야 한다.
⚠️ user.skills = [...fe, ...lang];는 user 객체의 프로퍼티 skills의 값을 [...fe, ...lang]으로 할당하겠다는 것이다.
let user = { name: "Mike" }
let info = { age: 30 };
let fe = ["JS", "React"];
let lang = ["Korean", "English"];
user = Object.assign(user, info, {skills:[]});
fe.forEach((item) => {
user.skills.push(item);
});
lang.forEach((item) => {
user.skills.push(item);
});
console.log(user); // {name: "Mike", age: 30, skills: ["JS", "React", "Korean", "English"]}
반면 객체 전개 구문을 사용하면 이렇게 짧은 코드로 문제를 해결 가능하다.
let user = { name: "Mike" }
let info = { age: 30 };
let fe = ["JS", "React"];
let lang = ["Korean", "English"];
user = {
...user,
...info,
skills: [...fe, ...lang],
}
console.log(user); // {name: "Mike", age: 30, skills: ["JS", "React", "Korean", "English"]}