본문 바로가기
프로그래밍 언어/JavaScript

[JavaScript] 나머지 매개변수, 전개 구문

by 민졈 2022. 3. 1.

 

 

이번 시간에는 나머지 매개변수와 전개 구문에 대해 알아볼 것이다.

 

 

. . .

 

 

이렇게 점 세개로 사용한다.

 

 

 

 

1. 나머지 매개변수

 

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

showName('Maria');  // 'Maria'

이렇게 name이라는 인수를 전달해주면 name을 콘솔에 찍는 함수이다.

 

 

만약 두개의 이름을 전달하면 어떻게 될까??

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

showName('Maria');  // 'Maria'
showName('Maria', 'John');  // ?

오류는 나지 않지만 콘솔에 Maria만 찍힌다.

 

 

자바스크립트에서 함수에 전달하는 인수에는 개수 제한이 없다.

인수의 개수를 정해놓고 함수를 만들어도 실제 호출할 때 정확히 그 개수를 맞출 필요는 없다.

 

아무것도 전달하지 않아도 에러는 발생하지 않지만 이름에 undefined가 찍힐 뿐이다.

 

 

함수의 인수를 얻는 방법은 두가지가 있다.

1. arguments

2. 나머지 매개변수

 

과거에는 1번만 사용할 수 있었지만 지금은 여러 장점이 있는 나머지 매개변수를 사용하는 추세이다.

우리가 자주 사용하는 화살표 함수에서는 arguments를 사용할 수 없다.

 

 

 

 

1 > arguments

  1) 함수로 넘어온 모든 인수에 접근할 수 있다.

  2) 함수내에서 이용 가능한 지역 변수이다.

  3) length / index를 사용해서 배열이라고 생각할 수 있지만 배열 형태를 가진 객체이다.

  4) 배열의 내장 메서드인 forEach, map은 사용할 수 없다.

 

function sayName() {
    console.log(arguments.length); // 받은 인수의 개수
    console.log(arguments[0]);
    console.log(arguments[1]);
}

sayName('Maria', 'John');

// 2
// 'Maria'
// 'John'

 

 

 

 

하지만 ES6를 사용하는 환경이라면 arguments가 아닌 나머지 매개변수구문 사용을 권장하고 있다.

 

2 > 나머지 매개변수(Rest parameters)

  1) 정해지지 않은 개수의 인수를 배열로 나타낼 수 있게 한다.

  2) 점 세개( ... )를 사용하고 그 뒤에 배열 이름을 정해준다.

  3) 함수를 호출할 때 아무것도 전달하지 않으면 undefined가 아닌 빈 배열이 나타난다

  4) 전달해주는 인수가 있다면 개수에 상관없이 전달받은 인수들을 배열로 담아준다.

 

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

showName(); // [ ]
showName('Maria');  // ['Maria']
showName('Maria', 'John');  // ['Maria', 'John']

 

조금 더 실용적인 예제로 나머지 매개변수를 사용해서 전달 받은 모든 수를 더해야하는 코드를 작성해보도록 하자.

 

 

arguments와는 다르게 배열의 형태가 아닌 실제로 배열을 만들어서 그 안에 값들을 넣어주는 것이기 때문에

배열에서 사용하는 forEach나 for문 등 내장 함수를 사용할 수 있다.

                            1. ...numbers로 이름을 정해서 배열을 만든다.
function
addNumbers(...numbers) {
    2. 누적해서 더해줄 변수를 초기화 시켜준다.
    let
result = 0;
    3. forEach를 사용해서 받아오는 인수를 누적해서 result에 더해준다. 
    numbers
.forEach((num) => {result += num});
    console.log(result);
}

addNumbers(1,2,3);  // 6
addNumbers(1,2,3,4,5,6,7,8,9,10);   // 55

 

 

forEach외에도 앞서 배웠던 reduce를 사용해 볼 수도 있다.

function addNumbers(...numbers) {
    let result = 0;
    numbers.reduce((prev, cur) => {prev += cur});
    console.log(result);
}

addNumbers(1,2,3);  // 6
addNumbers(1,2,3,4,5,6,7,8,9,10);   // 55

 

 

조금 더 실용적인 예제로 user 객체를 만들어주는 생성자 함수를 만들어보자

 

이름, 나이, 스킬을 인수로 받는데 사람마다 가지고 있는 기술은 각각 다르고 여러개일 수 있으니

스킬은 나머지 매개변수를 사용하여 배열로 만들어주었다.

아래와 같이 코드를 작성하면 스킬들이 여러개가 들어있는 배열로 만들어지는 것을 확인할 수 있다.

function User(name, age, ...skill) {
    this.name = name;
    this.age = age;
    this.skills = skills;
}

const user1 = new User('John', 28, 'html', 'css');
const user2 = new User('Maria', 32, 'React', 'JS');
const user3 = new User('May', 21, 'English', 'JS', 'React');

console.log(user1);
console.log(user2);
console.log(user3);

// 결과
/**
 * {
 * "name": "John",
 * "age": 28,
 * "skills":[ "html", "css" ]
 * }
 * {
 * "name": "Maria",
 * "age": 32,
 * "skills":[ "React", "JS" ]
 * }
 * {
 * "name": "May",
 * "age": 21,
 * "skills":[ "English", "JS", "React" ]
 * }
 */

 

 

주의해야할 점은 나머지 매개변수를 인수로 받으려면 인수의 맨 마지막에 위치해야 한다는 것이다.

 

 

 

 

 

2. 전개 구문(Spread syntax) 

 

 

1 > 배열

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

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

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

위의 ...arr1은 1,2,3을 나타내고 ...arr2는 5,6,7을 나타낸다.

 

또한 아래처럼 중간에 사용하는 것도 가능하다.

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

let result = [0, ...arr1, ...arr2, 8,9,10];

console.log(result);   // [1,2,3,5,6,7,8,9,10];

 

원래 배열에 집어넣고 arr.push( ), 중간에 빼고 arr.splice( ) 병합arr.concat( )하는 과정들은 굉장히 번거롭다.

이렇게 벌써 세가지의 내장 함수를 사용했다.

 

그런데 전개 구문을 사용한다면 위와 같이 쉽고 간단하게 할 수 있다.

 

 

 

2 > 객체

객체를 사용할 때도 간단하게 사용할 수 있다.

전에 사용했던 것처럼 Object.assign{ }을 사용할 필요도 없다.

let user = {name: 'John'};
let john = {...user, age: 28};

console.log(john);  // {name: "John", age: 28}

 

 

 

3 > 복제

let user = {name: 'John', age: 28};
let user2 = {...user};

user2.name = "Janny";

console.log(user.name); // "John"
console.log(user2.name);    //"Janny"

이렇게 전개 구문을 이용해서 user2의 이름을 바꾸어도 원래 user의 이름은 바뀌지 않는다.

user와 user2가 한개의 객체를 공유하는 것이 아니라

전개 구문을 이용해서 user2에는 user를 복사해서 넣었기 때문이다.

 

 

 

 

간단한 예제로 arr3을 [4,5,6,1,2,3]으로 만드는 코드를 작성해보자.

let arr3 = [1,2,3];
let arr4 = [4,5,6];

 

두개의 배열이 있으면 arr4만큼 돌면서 arr3에 unshift(앞에 추가)를 해주면 된다.

정말 간단하다!

arr4.forEach(num => {
    arr3.unshift(num);
});

 

 

라고 생각하고 console 창에 arr3을 표시해봤더니...

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

이렇게 나온다! 문제가 뭘까?

 

 

이유는 간단하다. unshift로 1앞에 4, 5, 6 순서로 넣어주기 때문이다.

그래서 우선 이 순서를 6, 5, 4 순서로 바꿔준 후 넣어줘야 한다.

 

 

그렇다면 순서를 바꿔주는 메소드는?!?!

 

 

 

 

 

reverse( ) ! !

let arr3 = [1,2,3];
let arr4 = [4,5,6];

arr4.reverse().forEach(num => {
    arr3.unshift(num);
});

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

그래서 위처럼 reverse를 사용해서 4,5,6의 순서를 바꾸고 1,2,3의 앞에 추가하는 unshift를 하면 우리가 하고자 했던데로 결과가 나오는 것을 볼 수 있다.

 

 

 

그런데 너무 복잡하다!!

 

거꾸로 순서를 나열하는 것까지 생각해야된다니..

 

 

그래서 전개 구문으로 위의 코드를 바꿔본다면

아래와 같이 된다

arr3 = [...arr4, ...arr3];

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

그냥 바로 arr4와 arr3을 넣어주면 된다! 얼마나 편한가..!!!!!

 

 

 

 

배열에 관련된 예제를 살펴보았으니, 이제 객체 관련 예제를 살펴보자.

let man = {name: 'John'};
let info = {age: 30};
let fe = ["JS", "React", "HTML"];
let lang = ["Korean", "Chinese", "English"];

 

객체 man에게 info , fe, lang을 넣어주는 코드를 전개 구문을 사용하지 않고 작성한다면

Object.assign을 통해 빈 객체를 만들어주고 fe와 lang은 skill이라는 배열을 만들어서 forEach를 사용해서 push 해주는 방법으로 작성하면 된다.

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

console.log(man);

//  {name: "John", age: 30, { skills: [ ] } }

skills.forEach((item) => {
    man.skills.push(item);
});

lang.forEach((item) => {
    man.lang.push(item);
});


console.log(man);
// {name: "John", age: 30, skills: ["JS", "React", "HTML", "Korean", "Chinese", "English"]}

 

작성하면서 너무 귀찮음을 느꼈다..

일일히 빈 객체를 만들고 forEach로 push 해주고...

 

 

하지만 전개구문을 사용한다면 아주 쉽게 만들어줄 수 있다.

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

// console.log(man);
// {name: "John", age: 30,
// skills: [0: "JS", 1: "React", 2: "HTML", 3: "Korean", 4: "Chinese", 5: "English"]}

 

 

 

 

앞으로 나머지 매개변수와 전개구문을 사용해서 간단하고 쉽게 코딩하는 개발자가 되도록 노력해보잣..!!!

 

 

 

 

 

 

 

* 본 포스팅은 코딩앙마님의 자바스크립트 중급 강의를 기반으로 작성한 글입니다.

 

 

 

댓글