JavaScript | Spread/Rest, 구조분해

SURI·2021년 11월 25일

1. 개념


1.1 Spread

배열을 풀어서 인자로 전달, 혹은 각각의 요소로 넣을 때 사용한다.

function sum(x, y, z) {
    return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers)); // 6

배열에서 사용하기

배열 합치기

let parts = ['shoulders', 'knees'];
let lyrics = ['head', ...parts, 'and', 'toes'];

console.log(lyrics);

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

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

console.table(arr1);
  • spread 문법은 기존 배열을 변경하지 않는다. arr1 값을 바꾸기 위해서 재할당을 해야 한다.

배열 복사

let arr = [1, 2, 3];
let arr2 = [...arr];
arr2.push(4);

console.table(arr);
console.table(arr2);
  • arr.slice()와 유사하게 spread 문법이 사용되었다.

객체에서 사용하기

let obj1 = {foo : 'bar', x :42};
let obj2 = {foo: 'baz', y:13};

let clonedObj = {...obj1};
let mergedObj = {...obj1, ...obj2};
  • mergedObj 부분이 재밌는 것 같다. obj1의 값을 먼저 가져오고 키가 중복되는 게 있으면 덮어써버렸다.
  • 배열에서는 요소가 중복된다고 overwrite 되는 부분이 있는 것 같지는 않다.

함수에서 나머지 파라미터 받아오기

function myFun(a, b, ...manyMoreArgs) {
  console.log("a", a);
  console.log("b", b);
  console.log("manyMoreArgs", manyMoreArgs);
}

myFun("one", "two", "three", "four", "five", "six");
a one
b two
manyMoreArgs ['three', 'four', 'five', 'six]
  • 나머지는 이렇게 배열의 형식으로 가져온다.
  • ...manyMoreArgs는 rest parameter, rest syntax라고 부른다. 남아 있는 모든 인자를 하나의 배열에 담기 때문이다.

1.2 Rest

파라미터를 배열의 형태로 받아서 사용할 수 있다. 파라미터 개수가 가변적일 때 유용하다.

function sum(...theArgs) {
  return theArgs.reduce((previous, current) => {
    return previous + current;
  });
}

sum(1,2,3) // 질문: 어떤 값을 리턴하나요?
sum(1,2,3,4) // 질문: 어떤 값을 리턴하나요?
  • 아 이부분 이해가 안 됐는데, 배열에서 reduce() 메서드가 있는 것 같다. 그 문법을 몰라서 이해가 안 되었던 것.

  • spread 문법으로 인자를 받으면 배열의 형태로 사용할 수 있다. 콘솔에 찍어보면 theArgs가 배열의 형태로 받아짐을 알 수 있다.

1.3 구조분해

Spread 문법을 이용하여 값을 해체한 후, 개별 값을 변수에 새로 할당하는 과정이다.

분해 후 새 변수에 할당

배열

const [a, b, ...rest] = [10, 20, 30, 40, 50];

 console.log(a); // 10
 console.log(typeof a); //number
 console.log(rest); // [30, 40, 50]

객체

const {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
// 질문: a, b, rest는 각각 어떤 값인가요?

객체에서 구조 분해 할당을 사용하는 경우, 선언(const, let, var)과 함께 사용하지 않으면 에러가 발생할 수 있습니다.
선언없이 할당하는 경우, 이 콘텐츠의 하단있는 공식문서 링크를 통해 내용을 확인할 수 있습니다.

  • 이렇게 객체나 배열을 분해해서 새로운 변수에 할당할 수 있다! 왜 이전까지는 개념이 모호했을까?
    • 객체에서는 키의 이름과 동일해야 받아올 수 있음을 알 수 있다.
    • 배열에서는 상관없이 변수에 값을 담는다.

함수에서 객체 분해

function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

let user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
      firstName: "John",
      lastName: "Doe"
  }
};

whois(user) 
  • 객체에서 내가 필요한 속성들만 취해서 가져올 수도 있긴 하겠구나. 함

2. 에러로그


let arr = [10, 30, 40, 20]
let value = Math.max(arr)

//let value = Math.max(...arr)
  • value의 값은 NaN이 나오게 된다.
  • Math.max에 숫자인 인자들을 비교해야 하는데 배열 자체를 넣었기 때문이다. 배열을 풀어서 인자로 전달하는 spread 문법을 사용하면 값이 나온다.
  • spread syntax는 iterable 한 모든 것의 (대표적으로 문자열, 배열) 요소를 펼쳐주는 문법을 의미한다.
let arr = ['code', 'states']
let value = [
  ...arr,
  'pre',
  ...['course', 'student']
]
  • 배열에 spread 문법을 사용해서 ...을 붙이니 펼쳐서 넣어주게 된다는 사실을 배움.

3. 질문


Q. 함수의 인자로 객체를 분해해서 받을 때, 그 값을 바꿔도.. 원본 객체가 바뀌진 않네? 이건 새로운 변수가 만들어지는 거라 그런건가?

profile
Every step to become a better version of me 🚶‍♂️ 블로그 이사중

0개의 댓글