[JS] Rest/Spread 문법과 구조분해 할당

somin·2021년 7월 2일

JavaScript

목록 보기
11/16

Rest 파라미터와 전개구문(Spread syntax)

1. 나머지 매개변수(Rest parameters)

function add(...numbers) { 
  let result = 0;
  numbers.forEach((num) => result += num)
  return result
}
add(1,2,3); //6
add(1,2,3,4,5,6,7,8,9,10); //55
  • 정해지지 않은 개수의 인수를 배열로 나타냄
  • 배열이기 때문에 배열 메소드 사용 가능
  • 몇개의 인자를 전달 받을 지 모를 때 사용
function User(name, age, ...skills){
  this.name =name;
  this.age = age;
  this.skills = skills;
}

const user1 = new User('somin', 26, 'html', 'css')
const user2 = new User('KKAKKA', 26, 'English')

console.log(user1)
// User {
//   name: 'somin',
//   age: 26,
//   skills: [ 'html', 'css' ],
// }

console.log(user2)
// User {
//   name: 'KKAKKA',
//   age: 26,
//   skills: [ 'English' ],
  • 나머지 매개변수는 항상 마지막에 위치

1) 매개변수(parameters)

function showName(name) {
  console.log(name);
}
showName('somin') //'somin'
showName('somin', 'KKAKKA') //'somin'(에러 발생 X)
showName() //undefined
  • 아무것도 입력하지 않으면 undefined 출력

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

function showName(...name) { //나머지 매개변수를 사용할 때
  console.log(name);
}
showName('somin') //[ 'somin' ]
showName('somin', 'KKAKKA') //[ 'somin', 'KKAKKA' ]
showName() //[]
  • Rest parameters : 출력이 배열로 나타나며 배열이기에 배열 메소드 사용 가능
  • 아무것도 입력하지 않으면 [] 출력

3) arguments

function getArgumentsObj() {
  return arguments;
}

const argumentsObj = getArgumentsObj("somin", "KKAKKA", "daeseong");

console.log(argumentsObj)
//{
//  '0': 'somin',
//  '1': 'KKAKKA',
//  '2': 'daeseong',
//  length: 3,
//}
console.log(argumentsObj.length)
//3
console.log(Object.keys(argumentsObj))
//[ '0', '1', '2' ]
console.log(Object.values(argumentsObj))
//[ 'somin', 'KKAKKA', 'daeseong' ]
  • arguments : 배열 형태의 객체로 유사 배열이지만 length 외 배열 메소드를 사용할 수 없음
    *모든 함수의 실행 시 자동으로 생성되는 '객체'

2. 전개구문(Spread syntax)

1) 형태

let myArr = [3, 4, 5];
let yourArr = [6, 7, 8];

let result1 = [...myArr, ...yourArr]
console.log(result1); 
//[ 3, 4, 5, 6, 7, 8 ]

let result2 = [0, 1, 2, ...myArr, ...yourArr, 9, 10] //중간에 넣을 수 있음
console.log(result2); 
//[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
  • ...으로 표현
  • 배열과 객체 모두 동일

2) 특징 : immutable

let myArr1 = [1, 2, 3];
let myArr2 = [...myArr1];

console.log(myArr1)//[ 1, 2, 3 ]
console.log(myArr2)//[ 1, 2, 3 ]

myArr1[1] = 4

console.log(myArr1) //[ 1, 4, 3 ]
console.log(myArr2) //[ 1, 2, 3 ] 
//별개의 배열로 복제된 것이므로 영향을 받지 않음
  • 주소가 아닌 값이 복사되므로 기존 배열을 변경하지 않으므로 복사 용이
  • 하지만 얕은 복사(shallow copy)이기에 배열/객체 안에 배열/객체의 경우는 주소가 복사되어 원본 데이터 변경

구조분해 할당

  • 배열이나 객체의 속성을 분해해 그 값을 변수에 담아 사용

1. 배열 구조분해(Destructing)

let users = ['somin', 'daeseong', 'KKAKKA'];
let [user1, user2, user3, user4] = users;

console.log(user1) //'somin'
console.log(user2) //'daeseong'
console.log(user3) //'KKAKKA'
console.log(user4) //undefined(해당하는 값이 없기 때문)
  • 기본값을 정해주면 undefined로 인한 오류 예방 가능
let users = ['somin', 'daeseong', 'KKAKKA'];
let [user1='1', user2='2', user3='3', user4='4'] = users;

console.log(user1) //'somin'
console.log(user2) //'daeseong'
console.log(user3) //'KKAKKA'
console.log(user4) //4(기본값 출력)

1) 메소드 사용

let str = 'somin daeseong KKAKKA';
let [user1, user2, user3] = str.split(' ') //str.split()은 배열로 출력

console.log(user1) //'somin'
console.log(user2) //'daeseong'
console.log(user3) //'KKAKKA'

2) 불필요한 요소 무시

let users = ['somin', 'daeseong', 'KKAKKA'];
let [user1, user2] = users;
console.log(user1) //'somin'
console.log(user2) //'daeseong'

let [user1, ,user2] = users;
//공백과 쉼표를 이용해 불필요한 배열 요소 무시할 수 있음
console.log(user1) //'somin'
console.log(user2) //'KKAKKA'

3) 변수의 값 바꿔치기

let a = 1;
let b = 2;
[a, b] = [b, a];

console.log(a)//2
console.log(b)//1

2. 객체 구조분해(Destructing)

  • 배열과 마찬가지고 기본값 부여 가능

1) 구조 분해

(1) 예시1

let user = {name: 'somin', age: 26, skill: 'English'};
let {name, age} = user;
//name과 age의 순서를 바꿔도 동일하게 작동

let {skill} = user;

console.log(name)//'somin'
console.log(age)//26
console.log(skill)//'English'

(2) 예시2

let user = {name: 'somin', age: 26, skill: 'English'};
let {name, age, skill: subject} = user;

console.log(name)//'somin'
console.log(age)//26
console.log(subject)//'English'

2) 변수 이름 바꾸기

let user = {name: 'somin', age: 26};
let {name: userName, age: userAge} = user;

console.log(userName)//'somin'
console.log(userAge)//26

3) rest/spread 문법 적용

(1) 예시1

let user = {name: 'somin', age: 26};
let {name, ...age} = user;

console.log(name)//'somin'
console.log(age)//{age: 26}

(2) 예시2

const user = {
  name: "somin",
  age: 26,
  cat: {
    name: "KKAKKA",
    age: 7,
    species: {
      name: "British Shorthair",
    },
  },
};

const changedUser = {
  ...user,
  name: "daeseong",
  age: 30,
};

console.log(changedUser)
//{
//  name: 'daeseong',
//  age: 30,
//  cat: {
//    name: 'KKAKKA',
//    age: 7,
//    species: { name: 'British Shorthair' }
//  }
//}

const changedCat = {
  ...user,
  cat: {
    ...user.cat,
    species: "Black Cat",
  },
};

console.log(changedCat)
//{
//  name: 'somin',
//  age: 26,
//  cat: { name: 'KKAKKA', age: 7, species: 'Black Cat' }
//}
  • ...user의 위치에 따라 내용이 덮어써질 수 있음
profile
✏️

0개의 댓글