JavaScript (12) # 나머지 매개변수, 전개 구문

준영·2022년 11월 23일
0
post-thumbnail

공부하기 전에..

이름을 콘솔로 찍어주는 함수를 만들었다.
다음과 같이 콘솔을 찍어보면 결과는 어떻게 나올까?

function showName(name){
  console.log(name);
}
showName('준영'); // '준영'
showName('준영', '두팔'), // '준영'
showName(); // undefined

첫번째와 두번째 경우에는 '준영'만 콘솔에 찍힌다. 하지만 알 수 있는 점은 함수에 인수를 전달하는 개수의 제한이 없다는 것이다. 따라서 인수의 개수를 정해놓은 함수여도 그 개수를 정확히 맞출 필요는 없다.

심지어 아무것도 전달하지 않아도 에러는 뜨지 않는다. 다만 undefined 만 찍힐 뿐...

그렇다면 함수에 인수를 막는 방법은 없는걸까?

  • 첫번째 방법은 arguments 로 접근하는 방법과, 다른 하나는 나머지 매개변수 를 사용하는 것이다.
    • (나머지 매개변수는 ... 으로 표현한다)

과거에는 arguments 만 사용이 가능했지만, 지금은 여러 장점이 있는 나머지 매개변수를 사용할 수 있을 뿐더러, 후자의 방법을 사용하는 추세이다. 결정적으로 화살표 함수에는 arguments를 쓸 수 없다!!!


그래서 arguments가 뭡니까?

  • 함수로 넘어 온 모든 인수에 접근 할 수 있다.
  • 함수내에서 이용 가능한 지역 변수이다.
  • lengthindex 가 있기 때문에, 배열이라고 생각할 수 있지만, 사실 Array 형태의 객체이다

Array 형태의 객체는 배열과 다르게 배열의 내장 메서드가 존재하지 않는다!! (forEach , map 사용 불가능)

function showName(name){
  console.log(arguments.length); // 2
  console.log(arguments[0]); // '준영'
  console.log(arguments[1]); // '두팔'
}
showName('준영', '두팔');

요즘 것의 나머지 매개변수(Rest parameters)

ES6를 사용할 수 있는 환경이라면, 가급적 arguments 보다는 나머지 매개변수 를 사용하는 것이 좋다.

나머지 매개변수는 정해지지 않은 개수의 인수를 배열로 나타낼 수 있게 한다. ... 를 찍고 배열의 이름을 정해주면 끝!

function showName(...names){
  console.log(names);
}
showName(); // []
showName('준영'); // ['준영']
showName('준영', '두팔'); // ['준영', '두팔']

인수를 주지 않으면, undefined 가 아닌 빈배열로 나타낸다. 이 얼마나 엄청난 녀석인가...


다른 응용? 예제? (전달 받은 모든 수를 더하는 함수)

function addAll(...numbers){
  let result = 0;
  numbers.forEach((num) => (result = result + num));
  console.log(result);
}

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

numbers 는 배열이기 때문에 당연히 length 가 존재하기 때문에, for문으로 사용이 가능하다.

또는 arguments 와는 다르게 배열의 메소드들도 사용이 가능하다!!


조금 더 실용적으로 접근해 보자 (user 객체를 만들어 주는 생성자 함수)

  • 생성자 함수의 이름 첫글자는 일반 함수와의 구분을 위해 항상 시작을 대문자로!
function User(name, age, ...skills){
  this.name = name;
  this.age = age;
  this.skills = skills;
}

const user1 = new User('준영', 26, 'JavaScript', 'React', 'Vue');
const user2 = new User('두팔', 3, 'html');
const user3 = new User('엥엥츈', 23, 'css', 'sass');

console.log(user1);
/*
User {
  name: '준영',
  age: 26,
  skills: [ 'JavaScript', 'React', 'Vue' ],
  __proto__: { constructor: ƒ User() }
}
*/

console.log(user2);
/*
User {
  name: '두팔',
  age: 3,
  skills: [ 'html' ],
  __proto__: { constructor: ƒ User() }
}
*/

console.log(user3);
/*
User {
  name: '엥엥츈',
  age: 23,
  skills: [ 'css', 'sass' ],
  __proto__: { constructor: ƒ User() }
}
*/

앞의 두개는 일반적인 변수로 받았고, 그 외의 인수들은 몇개가 들어올지 모르지만 나머지 매개변수로 받았다.

여기서 또한가지 알 수 있는 점은, 나머지 매개변수는 항상 제일 마지막에 위치 해야 한다는 점이다.


전개 구문 (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 ]

...arr11, 2, 3 을 풀어서 쓴 것이고, arr24, 5, 6 을 풀어서 쓴 것이다.

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

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

요렇게 중간에도 넣어서 사용할 수 있다.

전개 구문을 사용하면, arr,push() , arr.splice , arr.concat() 과 같은 복잡한 방법 없이 쉽게 배열을 만들 수 있다!!

👇 전개 구문을 사용하지 않으면...

// arr1을 [4,5,6,1,2,3,]으로 만들기

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 user = {name: '조준탄'};
let 조준탄 = {...user, age: 26};

console.log(조준탄) // { name: '조준탄', age: 26 }

객체도 마찬가지로 Object.assign() 이 필요없이 간단하게 쓸 수 있다!!

Object.assign() <= 객체를 병합하는 메소드

👇 전개 구문을 사용하지 않으면...

let user = { name: "준영" };
let info = { age: 26 };
let skills = [ "JavaScript", "React", "Vue" ];

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

skills.forEach((el) => {
  user.skills.push(el)
})

console.log(user);
/*
{
  name: '준영',
  age: 26,
  skills: [ 'JavaScript', 'React', 'Vue' ]
}
*/

복제

let arr = [1, 2, 3];
let arr2 = [...arr]; // [1, 2, 3]

let user = {name: '조준탄'};
let 조준탄 = {...user, age: 26};

조준탄.name = '곽두팔';

console.log(user.name) // '조준탄'
console.log(조준탄.name) // '곽두팔'

객체 조준탄 의 이름을 바꾸어도 user 의 이름에는 영향이 없다. 별개의 조준영 으로 복제된 것이다!!

profile
개인 이력, 포폴 관리 및 기술 블로그 사이트 👉 https://aimzero-web.vercel.app/

0개의 댓글