자바스크립트의 Spread 문법(...)은 배열이나 객체의 요소나 속성을 펼쳐서 새로운 배열이나 객체를 생성할 때 사용되는 문법입니다. Spread 문법은 다양한 상황에서 간편하게 데이터를 다룰 수 있게 해주며, 배열과 객체에 주로 사용됩니다.
1. 배열에서의 Spread 문법
배열의 각 요소를 펼쳐서 새로운 배열을 만들 수 있습니다.
배열 복사
Spread 문법을 사용하여 배열을 간단히 복사할 수 있습니다. (깊은 복사는 아님)
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2); // [1, 2, 3]
배열 결합
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4]
새로운 요소 추가
const arr = [2, 3];
const newArr = [1, ...arr, 4];
console.log(newArr); // [1, 2, 3, 4]
2. 객체에서의 Spread 문법
객체의 속성들을 펼쳐서 새로운 객체를 만들 수 있습니다. ES6 이후로 객체에서도 Spread 문법이 사용 가능해졌습니다.
객체 복사
객체의 모든 속성을 복사할 때 Spread 문법을 사용할 수 있습니다.
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1 };
console.log(obj2); // { a: 1, b: 2 }
객체 결합
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const combinedObj = { ...obj1, ...obj2 };
console.log(combinedObj); // { a: 1, b: 2 }
속성 덮어쓰기
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const newObj = { ...obj1, ...obj2 };
console.log(newObj); // { a: 1, b: 3, c: 4 }
3. 함수의 매개변수에서 Spread 문법
Spread 문법은 함수의 인자 목록을 쉽게 확장할 수 있도록 도와줍니다. 이는 가변 인자를 함수에 전달할 때 특히 유용합니다.
함수 호출에서 Spread 사용
function sum(x, y, z) {
return x + y + z;
}
const numbers = [1, 2, 3];
console.log(sum(...numbers)); // 6
인자 배열로 함수 호출
Spread 문법을 사용하면 배열을 개별 인자로 나누어 함수에 전달할 수 있습니다.
const nums = [5, 6, 7];
console.log(Math.max(...nums)); // 7
4. 기타 사용 사례
문자열을 배열로 변환
Spread 문법을 사용하여 문자열을 배열의 각 문자로 나눌 수 있습니다.
const str = "hello";
const letters = [...str];
console.log(letters); // ['h', 'e', 'l', 'l', 'o']
Rest와 함께 사용
Spread 문법은 rest 문법과 함께 사용되기도 합니다. Rest 문법은 함수의 매개변수에서 나머지 인자를 배열로 묶는 방식으로 작동하지만, 그 반대의 개념으로도 Spread 문법을 사용할 수 있습니다.
function showFirstAndRest(first, ...rest) {
console.log("First:", first);
console.log("Rest:", rest);
}
showFirstAndRest(1, 2, 3, 4);
// First: 1
// Rest: [2, 3, 4]
5. 복사와 참조의 차이점
Spread 문법은 얕은 복사(shallow copy)를 수행합니다. 즉, 배열이나 객체의 요소가 참조 타입(예: 배열, 객체)일 경우, 내부 객체는 여전히 동일한 참조를 공유합니다.
const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 };
obj2.b.c = 3;
console.log(obj1.b.c); // 3 (같은 객체 참조)
자바스크립트에서 객체, 배열, 함수 등은 참조 타입입니다. 즉, 이러한 값들은 실제로는 변수에 그 값 자체가 저장되는 게 아니라, 메모리 어딘가에 저장된 데이터의 주소를 참조합니다. 이 주소를 통해 해당 객체에 접근할 수 있습니다.
- 얕은 복사(shallow copy): 가장 바깥쪽의 객체나 배열의 1차 값만 복사되고, 내부의 객체나 배열은 같은 참조를 공유하게 됩니다.
- 깊은 복사(deep copy): 배열이나 객체 내부의 모든 값(심지어 내부의 객체들까지도) 완전히 새로운 복사본으로 만들어서, 원본과 복사본이 완전히 독립적으로 존재하게 됩니다
Spread 문법으로 얕은 복사할 때 어떻게 동작하는지
예를 들어, 객체를 spread 문법으로 복사하는 상황이라면
obj1을 복사하여 obj2를 만듭니다. 이때 obj2는 새로운 객체이기 때문에 겉으로 보기엔 obj1과 다릅니다. 예를 들어, name 속성을 변경하면 서로 영향을 받지 않습니다.
하지만 **address**는 객체이기 때문에 참조 타입입니다. 이 경우, obj1과 obj2는 같은 메모리 주소를 참조하고 있습니다. 그래서 한쪽에서 address 객체를 변경하면, 다른 쪽에서도 변화가 발생합니다.
이것이 얕은 복사의 핵심입니다. 가장 바깥쪽 객체는 복사되지만, 내부에 있는 객체나 배열 등 참조 타입들은 복사되지 않고 같은 참조를 공유합니다.
const obj1 = { name: 'John', address: { city: 'New York' } };
const obj2 = { ...obj1 };
obj2.name = 'Alice';
console.log(obj1.name); // 'John' (변경되지 않음)
console.log(obj2.name); // 'Alice'
obj2.address.city = 'Los Angeles';
console.log(obj1.address.city); // 'Los Angeles' (obj2에서 변경된 값이 반영됨)
console.log(obj2.address.city); // 'Los Angeles'
깊은 복사가 필요한 경우
만약 배열이나 객체 안에 중첩된 객체들이 있고, 이들을 완전히 독립적인 복사본으로 만들고 싶다면, 얕은 복사가 아닌 깊은 복사가 필요합니다.
깊은 복사를 하려면, Spread 문법만으로는 충분하지 않습니다. 이를 위해서는 재귀적으로 객체의 모든 깊이를 복사해야 하며, 자바스크립트 기본 기능으로는 JSON.parse(JSON.stringify()) 같은 방법이 있긴 하지만, 복잡한 데이터에서는 lodash의 cloneDeep() 같은 라이브러리를 사용하는 것이 좋습니다.
const _ = require('lodash');
const obj1 = { name: 'John', address: { city: 'New York' } };
const obj2 = _.cloneDeep(obj1); // 깊은 복사
obj2.address.city = 'Los Angeles';
console.log(obj1.address.city); // 'New York' (원본 변경되지 않음)
console.log(obj2.address.city); // 'Los Angeles'
'JAVASCRIPT' 카테고리의 다른 글
JAVASCRIPT ) 배열 고차 함수 (0) | 2024.07.30 |
---|---|
JAVASCRIPT ) 디스트럭처링 (0) | 2024.07.26 |
JAVASCRIPT ) Rest 파라미터 (0) | 2024.07.26 |
JAVASCRIPT ) 클로저 Closure (0) | 2024.07.25 |
JAVASCRIPT ) 자료구조 (0) | 2024.07.24 |