diff --git "a/\354\261\225\355\204\260_6/\354\203\201\353\262\224.md" "b/\354\261\225\355\204\260_6/\354\203\201\353\262\224.md" new file mode 100644 index 0000000..930e77a --- /dev/null +++ "b/\354\261\225\355\204\260_6/\354\203\201\353\262\224.md" @@ -0,0 +1,104 @@ +# 6장 - 변경 가능한 데이터 구조를 가진 언어에서 불변성 유지하기 + +## 장바구니 동작을 읽기, 쓰기 또는 둘 다로 분류하기 + +### 읽기 + +- 데이터에서 정보를 가져온다. +- 데이터를 바꾸지 않는다. + +### 쓰기 + +- 데이터를 바꾼다. + +카피-온-라이트는 쓰기를 읽기로 바꾼다. + +## 카피-온-라이트 원칙 세 단계 + +1. 복사본 만들기 +2. 복사본 변경하기 +3. 복사본 리턴하기 + +```jsx +// e.g +function add_elment_last(array, elem) { + let new_array = array.slice(); // 1. 복사본 만들기 + new_array.push(elem); // 2. 복사본 바꾸기 + return new_array; // 3. 복사본 리턴하기 +} +``` + +## 카피-온-라이트로 쓰기를 읽기로 변경하기 + +```jsx +// as-is +function remove_item_by_name(cart, name) { + let idx = null; + for(let i = 0; i < cart.length; i++){ + if(cart[i].name === name) + idx = i; + } + if(idx !== null) + cart.splice(idx, 1); // 장바구니 변경 => 쓰기 +} + +// to-be +function remove_item_by_name(cart, name) { + let idx = null; + for(let i = 0; i < cart.length; i++){ + if(cart[i].name === name) + idx = i; + } + if(idx !== null) + return removeItems(cart, idx, 1); // 함수처럼 재사용하기 쉽도록 일반화하여 리턴함 => 읽기 + return cart; +} +``` + +## 카피-온-라이트로 쓰기, 읽기 함수 분리하기 + +```jsx +// as-is +var a = [1, 2, 3, 4]; +var b = a.shift(); +console.log(b); // 1을 출력 <= 읽기 +console.log(a); // [2, 3, 4]를 출력 <= 쓰기 + +// to-be +function first_element(array){ + return array[0]; // 읽기 +} + +function drop_first(array){ + var array_copy = array.slice(); + array_copy.shift(); + return array_copy; // 읽기 +} + +function shift(array) { // 읽기만 하는 함수로 변경 완료 + return { + first : first_element(array), + array : drop_first(array) + } +} +``` + +## **불변 데이터 구조는 충분히 빠르다.** + +불변 데이터 구조는 변경 가능한 데이터 구조보다 메모리를 더 많이 쓰고 느리다. + +그러나 불변 데이터 구조를 사용하면서 대용량의 고성능 시스템을 구현하는 사례도 많다. + +이런 사례가 많다는 건 불변 데이터도 일반 앱이 쓰기 충분히 빠르다는 증거이다. + +- 불변 데이터 쓰면 좋은 점 + - 언제든 최적화 가능하다. + - 가비지 콜렉터는 매우 빠르다. + - 생각보다 많이 복사하지 않는다. + - 함수형 프로그래밍 언어에는 빠른 구현체가 있다. + +## **객체에 대한 카피-온-라이트** + +지금까지는 데이터가 배열이라는 가정 아래 **`.slice()`** 로 데이터를 복사했다. + +객체를 복사하려면 **`Object.assign({}, object)`** 를 사용하면 된다.