본문 바로가기

자바스크립트/기초

나머지 매개변수, 전개 구문(Rest parameters, Spread syntax)

이 글은 코딩앙마 자바스크립트 중급 강좌 #10 나머지 매개변수, 전개 구문(Rest parameters, Spread syntax) 를 정리한 글입니다.

 

인수 전달

function showName(name) {
      console.log(name);
}
showName('Mike'); // 'Mike'
showName('Mike', 'Tom'); // 'Mike'

name을 전달하면 name을 콘솔에 찍어주는 함수가 있다면, 이름을 하나 더 전달하면 에러는 발생하지 않고 mike만 찍힙니다.

자바스크립트에서 함수의넘겨주는 인수의 갯수는 제약이 없습니다. 인수의 갯수를 정해놓고 함수를 만들어도, 실제 호출할 때 정확히 그 갯수를 맞출 필요는 없습니다.

 

심지어 showName() 이렇게 아무것도 전달하지 않아도 에러는 발생하지 않고 undefined가 출력됩니다.

 

함수의 인수를 얻는 방법은 두가지가 있습니다. 하나는 arguments로 접근하는 방법이고 다른 하나는 나머지 매개변수를 사용하는 것입니다.

과거에는 arguments만 사용할 수 있었지만 지금은 여러 장점이 있는 나머지 매개변수를 사용하는 추세이고, 결정적으로 화살표함수에는 arguments가 없습니다. 

 

그럼 arguments가 뭔지 알아봅시다.

function showName(name){
     console.log(arguments.length);
     console.log(arguments[0]);
     console.log(arguments[1]);
}

showName('Mike', 'Tom');
// 2
// 'Mike'
// 'Tom'

arguments는 함수로 넘어 온 모든 인수에 접근할 수 있습니다.

함수내에서 이용 가능한 지역 변수입니다.

length / index가 있기 때문에 배열이라고 생각할 수 있지만, 사실 array형태의 객체입니다.

Array 형태의 객체는 length와 index 등 속성은 가지고 있지만, 배열의 내장 메서드는 가지고 있지 않아서 forEach나 map 등은 사용할 수 없습니다. 

위의 코드를 보면 arguments.length는 받은 인수의 갯수 2를 의미하고,

첫번째 인수는 'Mike'고 두번째 인수는 'Tom'이라고 알려줄 수 있습니다.

ES6문법을 사용할 수 있는 환경이면, 가급적 나머지 매개변수 구문 사용을 권장하고 있습니다.

 

그럼 나머지 매개변수를 알아보겠습니다.

function showName(...names){
   console.log(names);
}

showName(); // []
showName('Mike'); // ['Mike']
showName('Mike', 'Tom'); // ['Mike', 'Tom']

나머지 매개변수는 정해지지 않은 개수의 인수를 배열로 나타날 수 있게 합니다. 점 세개를 찍고 뒤에 배열이름을 사용해줍니다. 그러면 names배열 안에 전달된 인수들이 들어갑니다. 아무것도 들어가지 않으면 undefined가 아니라 빈 배열이 나타납니다.

 

조금 더 실용적인 예제를 보도록 하겠습니다.

// 나머지 매개변수
// 전달받은 모든 수를 더해야함

function add(...numbers) {
	let result = 0;
    numbers.forEach(num => (result += num));
    return result;
}

add(1, 2, 3);
add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

매번 전달하는 숫자의 갯수가 다르다고 가정하고 코드를 짠다면, 나머지 매개변수를 배열로 받아 forEach로 만들면 되겠죠? 초깃값을 0으로 두고 배열을 forEach로 반복해서 더해줍니다.

numbers는 배열이고 length가 있기 때문에 for문을 사용해도 되고, argument와 다르게 forEach와 같은 배열의 메소드들도 사용할 수 있습니다.

reduce를 사용해서 let result = numbers.reduce((prev, cur) => prev + cur); return result 이렇게 사용해도 됩니다.

 

조금 더 실용적인 예제를 보도록 하겠습니다.

// 나머지 매개변수
// 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');
const user3 = new User('Jane', 10, 'English');

console.log(user1); // User {name: "Mike", age: 30, skills: ["html", "css"]
console.log(user2); // User {name: "Tom", age: 20, skills: ["JS", "React"]
console.log(user3); // User {name: "Jane", age: 10, skills: ["English"]

이렇게 앞에 두 변수는 일반적인 변수로 받고, 그 외의 인수들은 몇개가 들어올지 모르지만 나머지 매개변수로 받았습니다. 주의하실 점은, 나머지 매개변수는 항상 마지막에 있어야합니다. 

 

다음은 전개 구문(Spread syntax) : 배열 입니다.

let arr1 = [1,2,3];
let arr2 = [4,5,6];

let result = [...arr1, ...arr2];

console.log(result); // [1,2,3,4,5,6]

...arr1은 1,2,3을 풀어서 쓴것 입니다. ...arr2는 4,5,6을 풀어서 쓴것이구요.

let result = [0, ...arr1, ...arr2, 7, 8, 9]; 이런식으로 중간에 사용하는 것도 가능합니다. // [0,1,2,3,4,5,6,7,8,9]

원래 배열에 넣고 중간에 빼고 병합하고 하는 작업들은 정말 번거롭습니다. 그런데, 전개 구문을 사용하면 간편하게 할 수 있습니다.

 

객체도 가능합니다.

let user = {name:'Mike', age:30};
let user2 = {...user};

user2.name = "Tom";

console.log(user.name); // "Mike"
console.log(user2.name); // "Tom"

user2의 name을 "Tom"으로 바꾸어도 user의 name에는 영향을 미치지않습니다. 별개의 user2로 복제가 된것입니다.

 

// 전개 구문
// arr1을 [4,5,6,1,2,3] 으로

let arr1 = [1,2,3];
let arr2 = [4,5,6];

arr2.forEach(num => {
   arr1.unshift(num)
}); 

console.log(arr1); // [6,5,4,1,2,3] 실패!

arr2.reverse().forEach(num => {
   arr1.unshift(num)
}); 

console.log(arr1); // [4,5,6,1,2,3] 성공했지만 복잡

arr1 = [...arr2, ...arr1];

console.log(arr1);  // [4,5,6,1,2,3] 간단하게 성공

전개 구문을 사용하면 간단하게 배열을 합칠 수 있습니다.

 

객체를 사용해보겠습니다.

let user = { name: "Mike" };
let info = { age: 30 };
let fe = ["JS", "React"];
let lang = ["Korean", "English"];

user = Object.assign({}, user, info, {skills : []})

console.log(user) // {name: "Mike", age: 30, 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"]}

// 전개 구문 사용

user = {
	...user,
    ...info,
    skills : [...fe, ...lang]
};

console.log(user) // {name: "Mike", age: 30, skills: ["JS", "React", "Korean", "English"]}

전개 구문을 사용하면 객체도 정말 간단하게 합칠 수 있습니다.

반응형