chapter 6~7
함수에 있는 동작을 불변형으로 만드는 방식 , 불편성의 원칙은 카피 온 라이트 라고 한다.
쓰기를 읽기로 바꾸는 것
카피-온-라이트 규칙
- 복사본 만들기
- 복사본 변경하기
- 복사본 리턴하기
이다.
ex> 카피-온-라이트로 바꾸어보기(배열)
//before
var mailing_list=[];
function add_contact(email){
mailing_list.push(email);
}
function submit_form_handler(event){
var form = event.target;
var email = form.elements["email"].value;
add_contact(email);
}
//after
var mailing_list=[];
function add_contact(email){
const new_mailing_list = mailing_list.slice();
new_mailing_list.push(email)
return new_mailing_list;
}
function submit_form_handler(event){
var form = event.target;
var email = form.elements["email"].value;
mailing_list = add_contact(email);
}
쓰기도 하고 읽기도 하는 동작
카피온라이트로 바꾸는 방법?
- 함수 분리하기(읽기,쓰기)
- 값을 두개 리턴하기
ex> 1. .shift() 함수를 읽기와 쓰기로 분리하기
funtion first_element(array){
return array[0];
}
function drop_first(array){
array.shift(); //쓰기 기능만 하기 때문에 return을 하지 않는다.
}
//카피온라이트로 바꾸기
function drop_first(array){
var array_copy = array.slice();
array_copy.shift();
return array_copy;
}
ex> 2. .shift() 의 값을 두개 리턴하는 함수로 만들기
function shift(array){
return array.shift();
}
//카피온라이트로 변경
function shift(array){
var array_copy = array.slice();
var first = array_copy.shift();
return {
first: first,
array: array_copy
};
}
결론
변경 가능한 데이터를 읽는것은 액션 이다.
불변데이터 구보를 읽는 것은 계산 이다.
시간에 따라 변하는 상태
모든 데이터가 불변형이라면 애플리케이션에서 시간에 따라 변하는 상태를 어떻게 다뤄야 할까?
교체를 한다. 필요할때 새로운 값으로 교체한다. 그럼 되돌리기 할때 쉽게 구현 할 수 있음
객체의 카피-온-라이트
객체복사본 만드는 메서드는 Object.assign()
으로 만든다.
얕은 복사는 중첨된 데이터 구조에 최상위 데이터만 복사한다. 예를 들어 객체가 들어있는 배열이 있으면 얕은 복사는 배열만 하고 안에있는 객체는 참조로 공유한다.
두개의 중첩된 데이터 구조가 어떤 참조를 공유한다면 구조적 공유라고 한다. 데이터가 바뀌지 않는 불변데이터 구조라면 구조적 공유는 안전하다. 메모리를 적게 사용하고 , 빠르다는 특징을 갖고있다.
중첩된 쓰기를 읽기로 바꾸기
function setPriceByName (cart, name, price) {
var cartCopy = cart.slice ();
// =============> 얕은 복사(참조)
for (var i = 0; i < cartCopy.length; i++) {
if (cartCopy [i].name === name)
cartCopy[i] = setPrice (cartCopy [il, price);
}
return cartCopy;
}
function setPrice (item, new price) {
var item copy = Object.assign ({}, item);
//========> 얕은 복사 , 티셔츠 객체를 복사하여 가격을 설정한다.
item copy.price = new _price;
return item copy;
}
2번 복사한다.
결론
- 카피-온-라이트는 데이터를 불변형으로 유지할 수 있는 원칙 이다. 복사본을 만들고 원본 대신 복사본을 변경하는 것을 말한다.
- 카피-온-라이트는 값을 변경하기 전에 얕은 복사를 하고 리턴한다.
레거시 코드와 불변성
레거시 코드에 쓸수 있는 카피-온-라이트 원칙을 지키며 안전하게 함수를 사용할 수 있는 또 다른 원칙은 방어적 복사 라고 한다.
깊은 복사본을 만둘고, 변경 가능한 원본은 버린다.
“방어적 복사” 를 사용하면 데이터가 바뀌는 것을 막아 불변성을 지킬 수 있다. 원본을 바뀌지 않도록 막아주기 때문에 “방어적” 이라고 한다.
ex>
//before
function xxx(){
... ..
....
add_example(global_cart);
}
//after
function xxx(){
... ..
....
var copy_global_cart = deepCopy(global_cart); //데이터를 넘기기 전에 복사한다.
add_example(copy_global_cart);
global_cart = deepCopy(copy_global_cart); //들어오는 데이터를 위한 복사
}
방어적 복사 규칙
깊은복사는 위에서 아래로 모든 계층에 있는 중첩된 데이터 구조를 복사한다.
- 데이터가 안전한 코드에서 나갈 때 복사하기
→ 원본 데이터를 보호할 수 있다. - 안전 한 코드로 데이터가 들어올 때 복사하기
카피-온-라이트 vs 방어적 복사
언제 사용 | 통제할 수 있는 데이터를 바꿀때 | 신뢰할 수 없는 코드와 데이터를 주고받아야할 때 |
어디서 사용 | 안전지대 어디서나 사용 가능 | 안전지대 경계에서 데이터가 오고갈때 |
복사방식 | 얕은 복사(비용이 적게 든다) | 깊은 복사(비용이 많이 든다) |
규칙 | 1. 바꿀 데이터의 얕은 복사를 만든다 2. 복사본을 변경한다. 3. 복사본을 리턴한다 |
|
깊은 복사
원본과 어떤 데이터 구조도 공유하지 않는 것이 얕은 복사와 차이이다. 중첩된 모든 객체나 배열을 복사한다.
데이터가 변경되면 안되지만, 신뢰할 수 없는 코드가 변경할지도 모른다면 깊은 복사를 사용해야 한다.
lodash
.cloneDeep()
를 사용하는 것 추천
결론
- 방어적 복사는 불변성을 구현하는 원칙이다. 데이터가 들어오고 나갈때 복사본을 만든다.
- 깊은 복사를 한다(비용 많이 든다)
- 불변성원칙을 구현하지 않는 코드로부터 데이터를 보호해줌
'BOOKS' 카테고리의 다른 글
[실전에서 바로쓰는 Next.js] Next.js 기초와 내장 컴포넌트 (0) | 2023.05.10 |
---|---|
[실전에서 바로쓰는 Next.js] 렌더링 전략 (0) | 2023.05.05 |
[웹 성능 최적화 기법]웹에서 가속을 끌어내는 방법 (0) | 2023.04.10 |
[웹 성능 최적화 기법]웹 사이트 개선 방법 (0) | 2023.03.01 |
[웹 성능 최적화 기법]웹 최적화 (0) | 2023.02.26 |