JavaScript

JavaScript spread 연산자

somedding 2023. 8. 28. 22:49

Spread

spread operator는 영어 해석 그대로 '펼치는 연산자'이다.

결국 이 문법을 사용해서 배열 같은 iterable 객체와 일반적인 enumerable 객체를  여러 개의 요소로 펼치는 곳에 사용할 수 있다.

즉, 배열 혹은 객체 등을 펼칠 수 있다.

 

spread 문법은 배열과 객체를 확장하거나 병합하는 데 사용되는 유용한 기능 중 하나이다.

기존의 배열 혹은 객체의 요소나 속성을 새로운 배열 혹은 객체로 복사하거나 병합할 수 있다.

 

우선 배열에서의 spread 문법이다.

const array = [1, 2, 3];
const copiedArray = [...originalArray];

console.log(array); // [1, 2, 3]
console.log(copiedArray); // [1, 2, 3]

여기서 사용한 ' ... ' 이 바로 spread 연산자이다.

spread 연산자를 사용하여 배열을 '복사'할 수 있다.

 

const array = [1, 2, 3];
const addedArray = [...array, 4];

console.log(array); // [1, 2, 3]
console.log(addedArray); // [1, 2, 3, 4]

 

이렇게 기존의 배열은 건드리지 않으면서 새로운 addedArray에 array의 내용을 집어넣고, 마지막에 4라는 값을 추가했다.

 

또한

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];

const mergedArray = [...array1, ...array2];
console.log(mergedArray); // [1, 2, 3, 4, 5, 6]

이런 식으로 두 배열을 병합할 수도 있다.

 

 

객체에서의 spread 문법도 동일하다.

const obj = { x: 1, y: 2 };
const copiedObj = { ...obj };

console.log(obj); // { x: 1, y: 2 }
console.log(copiedObj); // { x: 1, y: 2 }

 

spread 연산자를 사용하여 객체를 '복사'할 수 있다.

 

const obj = { x: 1, y: 2 };

const addedObj = { ...obj1, z: 3 };
console.log(addedObj); // { x: 1, y: 2, z: 3 }

이렇게 기존의 객체는 건드리지 않으면서 새로운 addedObj에 obj의 내용을 집어넣고, 마지막에 z: 3이라는 값을 추가했다.

 

마찬가지로

const obj1 = { x: 1, y: 2 };
const obj2 = { z: 3 };

const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // { x: 1, y: 2, z: 3 }

이런 식으로 두 객체를 병합할 수도 있다.

 

 

 

하지만 spread 연산자에는 주의할 점이 있다.

const obj = { x: 1, y: 2, z: [3, 4] };
const copiedObj = { ...obj };

console.log(obj); // { x: 1, y: 2, z: [ 3, 4 ] }
console.log(copiedObj); // { x: 1, y: 2, z: [ 3, 4 ] }

이런 값을 가지는 객체가 존재한다고 가정해 보자.

 

이때 copiedObj의 'z'속성은 배열이고, 이 배열에 5를 추가한다고 가정해 보자.

그러면

copiedObj.z.push(5)

를 작성할 것이다.

const obj = { x: 1, y: 2, z: [3, 4] };
const copiedObj = { ...obj };

copiedObj.z.push(5);

이렇게 했을 때 obj와 copiedObj를 출력해 보자.

console.log(obj); // { x: 1, y: 2, z: [ 3, 4, 5 ] }
console.log(copiedObj); // { x: 1, y: 2, z: [ 3, 4, 5 ] }

뭔가 이상하다.

분명 copiedObj의 'z'에만 값을 추가했는데, obj의 'z'에도 값이 추가되어 있다.

 

 

이것은 spread 연산자가 가지는 특징(?) 때문이다.

spread 연산자는 앞서 말했듯이 '복사'를 해준다.

하지만 '복사'라는 것은 '얕은 복사', '깊은 복사'로 나눌 수 있다.

이때, spread 연산자는 '얕은 복사'를 진행하게 되는데, 이는 내부 객체나 배열은 여전히 원본 객체와 같은 객체를 참조할 수 있다.

얕은 복사와 깊은 복사에 대한 내용은 추후에 새로 작성할 예정이다.

 

 

결국 위 예시에서 obj와 copiedObj는 'z'라는 배열을 공유하고 있으므로,

복사본에서 배열에 새로운 요소를 추가하면 원본 객체도 영향을 받게 된다.

 

그리고 이것이 얕은 복사의 한계가 된다.

 

만약 내부 객체나 배열까지 별도로 복제하여 독립적으로 다루고 싶다면 깊은 복사를 수행해야 한다.

 

 

 

 

 

글 내용 중, 잘못됐거나 더 알아야 하는 지식이 있다면 댓글로 남겨주시면 감사하겠습니다!

모두 좋은 하루 보내세요:)