728x90
※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.
spread 구문
...foo 와 같은 형태로 기재되며, 배열이나 오브젝트의 요소를 문자 그대로 전개하는 구문이다. 단순한 정의로는 어떤 구문인지 한번에 이해하기 어려울 것 같으므로, 배열과 오브젝트 각각의 경우를 살펴보자.
배열
const foo = [1, 2];
// 배열의 복사
const bar = [...foo]; // => [1, 2]
// 요소를 추가하여 새로운 배열을 생성
const baz = [...foo, 3, 4]; // => [1, 2, 3, 4]
// 배열 합치기
const hoge = [...foo, ...bar]; // => [1, 2, 1, 2]
Array.prototype.concat()과 상응하지만 더욱 간단하게 작성할 수 있다.
오브젝트
const foo = { a: 1, b: 2 };
// 오브젝트의 복사
const bar = { ...foo }; // => { a: 1, b: 2 }
// 속성을 추가한 새로운 오브젝트를 생성
const baz = { ...foo, c: 3 }; // => { a: 1, b: 2, c: 3 }
// 오브젝트 합치기
const hoge = { ...foo, ...{ c: 3, d: 4 } }; // => { a: 1, b: 2, c: 3, d: 4 }
// 원래의 오브젝트에 같은 이름의 속성이 있는 경우 치환
const fuga = { ...foo, b: 3 }; // => { a: 1, b: 3 }
const piyo = { ...foo, ...{ a: 3, b: 4 } }; // => { a: 3, b: 4 }
Object.assign()으로 작성한 것과 같은 치환이 가능하다.
주의해야할 점
배열이든 오브젝트든 spread 구문은 shallow copy이므로, 들여쓰기가 있는 경우 주의해야할 필요가 있다.
const foo = {
a: {
b: 1
}
};
const bar = { ...foo };
foo.a.b = 2;
console.log(bar); // => { a: { b: 2 } }
자식 오브젝트는 동일하게 참조하고 있다는 것을 알 수 있다. 들여쓰기되어 있는 오브젝트를 다룰 때에는 다음과 같이 개별로 분할할 필요가 있다.
const foo = {
a: {
b: 1,
c: 2
},
d: 3
};
const bar = {
...foo,
a: {
...foo.a,
c: 4
}
};
console.log(bar); // => { a: {b: 1, c: 4}, d: 3 }
분할 대입(Destructuring assignment)
분할 대입은 배열이나 오브젝트의 요소를 일부 획득해 개별 변수에 대입할 수 있다.
const array = [1, 2, 3];
const [x, y, z] = array;
console.log(x); // => 1
console.log(y); // => 2
console.log(z); // => 3
const obj = { foo: 1, bar: 2, baz: 3 };
const { foo } = obj;
console.log(foo); // => 1
이 구문과 spread를 합쳐서 요소를 빼내면서 변수에 대입할 수 있다.
const array = [1, 2, 3];
const [p, ...q] = array;
console.log(p); // => 1
console.log(q); // => [2, 3]
const obj = { foo: 1, bar: 2, baz: 3 };
const { foo, ...rest } = obj;
console.log(foo); // => 1
console.log(rest); // => { bar: 2, baz: 3 }
한편 들여쓰기한 오브젝트라면 이런 느낌이다.
const nestedObj = {
x: { a: 1, b: 2, c: 3 },
y: [4, 5, 6]
};
const { x: { a, ...restX }, y: [y0, ...restY] } = nestedObj;
console.log(a); // => 1
console.log(restX); // => { b: 2, c: 3 }
console.log(y0); // => 4
console.log(restY); // => [5, 6]
(여담) Redux Reducer을 이용한 사용예
spread 구문은 오브젝트를 Immutable하게 다루는 경우에도 활용할 수 있다. 그 하나의 예로 Redux의 State/Reducer가 있기 때문에 간단히 여기서 소개하고자 한다.
interface Todo {
id: number;
text: string;
completed: boolean;
}
interface TodoState {
todos: { [id: number]: Todo };
}
const todoReducer = (state: TodoState = { todos: {} }, action: TodoAction): TodoState => {
switch (action.type) {
case TypeKeys.ADD_TODO:
const nextId = Object.keys(state.todos).length + 1;
return {
todos: {
...state.todos,
[nextId]: {
id: nextId,
text: action.payload.text,
completed: false
}
}
};
case TypeKeys.COMPLETE_TODO:
return {
todos: {
...state.todos,
[action.payload.id]: {
...state.todos[action.payload.id],
completed: true
}
}
};
default:
return state;
}
};
참고자료
728x90
'IT > 언어' 카테고리의 다른 글
[JavaScript] some과 every (0) | 2023.03.21 |
---|---|
[JavaScript] Object.entries()를 사용하여 Object를 배열로 변환하기 (0) | 2023.03.13 |
[JavaScript] async/await 입문 (0) | 2023.03.05 |
[JavaScript] 깔끔한 조건문을 작성하는 방법 (0) | 2023.02.27 |
[Vue.js/Vuetify] v-select 사용법 (0) | 2023.02.20 |