함수를 호출할때 ...arr를 사용하면, 이터러블 객체 arr이 인수 목록으로 '확장'됩니다.
let arr = [3,5,1];
alert(Math.max(...arr)); // 5 (스프레드 문법이 배열을 인수 목록으로 바꿔주었습니다.
아래와 같이 이터러블 객체 여러 개를 전달하는 것도 가능합니다.
let arr1 = [1,-2,3,4];
let arr2 = [8,3,-8,1];
alert(Math.max(...arr1, ...arr2)); //8
스프레드 문법은 평범한 값과 혼합해 사용하는 것도 가능합니다.
let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];
alert(Math.max(1, ...arr1,2,...arr2,25)); //25
스프레드 문법은 배열을 합칠 때도 활용할 수 있습니다.
let arr = [3, 5, 1];
let arr2 = [8, 9, 15];
let merge = [0, ...arr, 2, ...arr2];
alert(merged);
//[
// 0, 3, 5, 1,
// 2, 8, 9, 15
//]
앞선 예시들어선 '배열'을 대상으로 스프레드 문법이 어떻게 동작하는지 살펴보았습니다. 그런데 배열이 아니더라도 이터러블 객체이면 스프레드 문법을 사용할 수 있습니다.
스프레드 문법을 사용해 문자 배열로 변환 시켜 보겠습니다.
let str = "Hello";
console.log([...str]);
//[ 'H', 'e', 'l', 'l', 'o' ]
스프레드 문법은 for...of 와 같은 방식으로 내부에서 이터레이터(iterator, 반복자)를 사용해 요소를 수집합니다.
문자열에 for..of 를 사용하면 문자열을 구성하는 문자가 반환됩니다. ...str 도 H,e,l,l,o 가 되는데, 이 문자 목록은
배열 초기자(array initializer) [...str]로 전달됩니다.
메서드 Array.from은 이터러블 객체인 문자열을 배열로 바꿔주기 때문에 Array.from 을 사용해도 동일한 작업을 할 수 있습니다.
let str = "Hello";
// Array.from은 이터러블을 배열로 바꿔줍니다.
alert( Array.from(str) ); // H,e,l,l,o
Array.from(obj)와 [...obj] 는 다음과 같은 미묘한 차이가 있습니다.
- Array.from은 유사 배열 객체와 이터러블 객체 둘다에 사용할 수 있습니다.
- 스프레드 문법은 이터러블 객체에만 사용할 수 있습니다.
이런 이유 때문에 무언가를 배열로 바꿀 때는 스프레드 문법보다 Array.from 이 보편적으로 사용됩니다.
배열과 객체의 복사본 만들기
참조에 의한 객체 복사 챕터에서 Object.assign() 을 사용해 객체를 복사한 예시를 떠올려봅시다.
Object.assign() 말고도 스프레드 문법을 사용하면 배열과 객체를 복사할 수 있습니다.
let arr = [1, 2, 3];
let arrCopy = [...arr]; // 배열을 펼쳐서 각 요소를 분리후, 매개변수 목록으로 만든 다음에
// 매개변수 목록을 새로운 배열에 할당함
// 배열 복사본의 요소가 기존 배열 요소와 진짜 같을까요?
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true
// 두 배열은 같을까요?
alert(arr === arrCopy); // false (참조가 다름)
// 참조가 다르므로 기존 배열을 수정해도 복사본은 영향을 받지 않습니다.
arr.push(4);
alert(arr); // 1, 2, 3, 4
alert(arrCopy); // 1, 2, 3
이번엔 객체를 복사하는 예시를 살펴보겠습니다.
let obj = { a: 1, b: 2, c: 3 };
let objCopy = { ...obj }; // 객체를 펼쳐서 각 요소를 분리후, 매개변수 목록으로 만든 다음에
// 매개변수 목록을 새로운 객체에 할당함
// 객체 복사본의 프로퍼티들이 기존 객체의 프로퍼티들과 진짜 같을까요?
alert(JSON.stringify(obj) === JSON.stringify(objCopy)); // true
// 두 객체는 같을까요?
alert(obj === objCopy); // false (참조가 다름)
// 참조가 다르므로 기존 객체를 수정해도 복사본은 영향을 받지 않습니다.
obj.d = 4;
alert(JSON.stringify(obj)); // {"a":1,"b":2,"c":3,"d":4}
alert(JSON.stringify(objCopy)); // {"a":1,"b":2,"c":3}
이렇게 스프레드 문법을 사용하면 let objCopy = Object.assign({},obj);, let arrCopy = Object.assign([],arr); 보다 더 짧은 코드로
배열이나 객체를 복사할 수 있어서 사람들은 이 방법을 선호하는 편입니다.
정리
스프레드 문법이라는 것을 오늘 처음 알게 된거 같다. 정확히는 스프레드 문법이라는 말을 처음들었고 사용은 해본거 같다.
스프레드 문법을 사용할 때, 누가 "이게 스프레드 문법이야" 라고 말해주진 않았기 때문에 문법의 이름을 몰랐던거 같다. 스프레드 문법을
사용하면서 이게 왜 이렇게 들어가지 라는 생각이 많이 들긴 했는데, 오늘에서야 궁금증이 해소된거같다.
스프레드 문법은 이터러블 객체이면 사용이 가능하고 이터러블 객체를 배열로 바꿔주는 좋은 기능인거같다.
'javascript' 카테고리의 다른 글
require vs import 문법 비교하기 (0) | 2023.06.07 |
---|---|
Method Chaining (함수 연달아 쓰기) (0) | 2023.02.14 |
소수 출력하는 알고리즘 (0) | 2023.02.13 |
문자열 비교 (0) | 2023.02.13 |
옵셔널 체이닝 (0) | 2023.02.12 |