-
불변성에 대해2 : Nested Object, 방어적 복사, 불변객체생성JavaScript 2022. 9. 23. 18:03
1. 객체의 방어적 복사 : Object.assign
Object.assign(target, ...sources)
Object.assign은 타킷으로 후자의 프로퍼티를 복사한다.
const o1 = {name:'kim'} const o2 = {name:'kim'} console.log(o1 === o2) // fasle
1번 김씨와 2번 김씨는 같지 않다.
값과 자료타입이 같아도, b)데이터 영역의 주소가 다르다.
const o1 = {name:'kim'} const o2 = o1 o2.name = 'lee' console.log(o1, o2, o1.name, o2.name) // { name: 'lee' } { name: 'lee' } lee lee
그러나 변수 영역에서 재할당을 하고, b)데이터 영역의 주소를 가져왔다.
참조관계가 된 것이다.
그리고 2번 아저씨가 이씨로 성을 갈아버리자, 1번 아저씨도 성이 바뀌어 버렸다.
대안1 : 방어적 복사
const o1 = {name:'kim', score:[1,2]} const o2 = Object. assign({}, o1); o2.name = 'lee' console.log(o1, o2, o1 === o2, o1.score === o2.score) // 출력 { name: 'kim', score: [ 1, 2 ] } { name: 'lee', score: [ 1, 2 ] } false true
방어적 복사를 수행했다.
o2 아저씨는 Object.assign() 함수를 통해 프로퍼티를 복사해왔다.
이제 2번 아저씨가 성을 갈아도 1번 아저씨의 성씨는 안전하다.
"복사"라고는 하지만, 사실 다른 Propoerty의 영역을 할당받고 갈라진 것이다.
o1 객체 김씨, 그리고 그 객체를 할당(assign) 받은 객체 o2.
o1과 o2는 같은 값과 자료형을 가지고 있지만, 일치연산자는 false라고 말한다.
무엇이 같지 않은가? property 주소가 같지 않다.
값도 자료형도 같아도, 같은 메모리 공간의 같은 데이터를 공유하는 것이 아니라는 뜻이다.
그러나 중첩된 객체(Nested Object)의 경우,(위 예시에서는 score) 같은 메모리 공간에 대한 property 경로가 복사되어 있다.
따라서 o1.score === o2.score 는 true가 뜬다.
저 true는 김씨와 이씨의 불행의 씨앗이다.
즉, 참조관계라는 것이다.
따라서 아래와 같은 불행이 일어난다.
const o1 = {name:'kim', score:[1,2]} const o2 = Object. assign({}, o1); o2.score.push(3) console.log(o1, o2, o1 === o2, o1.score === o2.score) //출력 { name: 'kim', score: [ 1, 2, 3 ] } { name: 'kim', score: [ 1, 2, 3 ] } false true
o2 아저씨의 점수에 3을 밀었는데, o1 김씨의 점수에도 3이 들어가는 것이다.
const o1 = {name:'kim', score:[1,2]} const o2 = Object. assign({}, o1); o2.score = o2.score.concat() o2.score.push(3) console.log(o1, o2, o1 === o2, o1.score === o2.score) //출력 { name: 'kim', score: [ 1, 2 ] } { name: 'kim', score: [ 1, 2, 3 ] } false false
function fn(person){ person.name = 'lee'; } var o1 = {name:'kim'} fn(o1); console.log(o1); //출력 { name: 'lee' }
'JavaScript' 카테고리의 다른 글
스코프 (1) 2022.09.23 호이스팅 Hoisting (0) 2022.09.23 불변성에 대해1 : 기본형 데이터와 참조형 데이터 (0) 2022.09.23 형변환 (type casting)1 : 문자열과 숫자 (1) 2022.09.23 느슨한 타입(loosely typed)의 동적(dynamic) 언어 (0) 2022.09.23