문제 설명
얕은 복사와 깊은 복사를 공부하고 있었다. 얕은 복사가 어떤 방식으로 객체를 카피 하는지 이해했고 이를 방지하기 위해서 깊은 복사로 불리는 함수를 이용해야 한다는 것도 이해했다.
var copyObjectDeep = function(target) {
var result = {};
if (typeof target === 'object' && target !== null) {
for (var prop in target) {
result[prop] = copyObjectDeep(target[prop]);
}
} else {
result = target;
}
return result;
}
위의 함수가 깊은 복사 함수의 알고리즘이다.
이 알고리즘이 어떻게 깊은 복사를 이뤄내는지 감이 잡히지 않았다.
시도
일단 한 줄씩 천천히 읽어내려갔다.
var copyObjectDeep = function(target) 첫줄, 식별자copyObjectDeep에 함수를 변수로 할당했다. 함수의 매개변수는 target이다. 다행히 콜백함수는 아니다. 두번째 줄 부터 함수의 알고리즘이 시작된다.
var result = {}; 우선 식별자 result에 빈 객체 {} 를 할당했다.
if (typeof target === 'object' && target !== null) 그리고 if문에 조건을 걸었다. 첫 번째typeof target === 'object' 이는 함수의 매개변수가 객체여야 한다는 뜻, 두 번째 조건은 target !== null 그리고 빈 값이 아니어여 한다는 것. && 그리고 논리 연산자 곱. 두 조건이 모두 참일 때 if문이 발동한다.
for (var prop in target), if문이 참일때 for in 문이 발동된다. for in 문은 객체의 속성을 출력한다. target은 무조건 객체일 것이니 target의 객체의 속성이 prop에 할당된다.
result[prop] = copyObjectDeep(target[prop]) 그리고 이곳
result는 객체다. 즉 result의 [prop] 값은 =copyObjectDeep(target[prop]) 이것과 똑 같다고 할 수있다.
copyObjectDeep()은 지금의 알고리즘이 행해지는 함수다. 즉 자신 알고리즘으로 진행되는 과정에서 또 자신의 알고리즘이 진행이 되는 재귀 함수다.
target[prop] 이건. 일단 prop는 target의 객체의 속성이다. 즉 target의 값이 copyObjectDeep()의 매개변수로 작동이 된다는 뜻이다.
여기까지 코드리딩을 진행했지만 더 이상은 현재 내 수준의 직관으로는 해독하기 힘들었다. 그래서 vs코드를 통해서 좀 더 자세히 알아봐야 겠다. console.log를 통해
해결
var obj = {
a: 1,
b: {
c: null,
d: [1, 2],
}
};
var obj2 = copyObjectDeep(obj);
obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;
객체를 만들고 함수 속에 console.log()를 넣어서 어떤 데이터가 들어가는지 알아보자!
for (var prop in target) {
result[prop] = copyObjectDeep(target[prop]);
console.log(target[prop])
}
함수의 알고리즘에 이해가 안가는 부분을 찍어보았다.
1, null, 1, 2, [ 1, 2 ], { c: null, d: [ 1, 2 ] } 가 나왔다. target 즉 obj의 요소가 말 그대로 전부 함수의 매개변수로 작용한다는 뜻이다. 천천히 생각하자, 우선 1, 1은 a 키의 값이다. 1이 copyObjectDeep() 함수를 돌면 if의 조건에 해당하지 않기 때문에 else {result = target;} 으로 간다.
잊지 말아야 할 것ㅡ 지금 이 결과는 재귀함수였다. 즉 result[prop]=1 이라는 것, result[a]=1 이라는 것, a키의 값이 1이라할당 한다는 뜻이다.!
result[prop] = copyObjectDeep(target[prop]);는 키값을 다시 할당하는 역할을 하고 있다는 의미다.
객체부분을 정리하면
result[b]= copyObjectDeep({c: null,d: [1, 2],})
copyObjectDeep({c: null,d: [1, 2],})=function(target) //재귀함수//
copyObjectDeep(b)=function({c: null,d: [1, 2],}) //재귀함수// 그리고 또 다시
copyObjectDeep(c)=function(null) //재귀함수의 재귀함수//
copyObjectDeep(d)=function([1, 2]) //재귀함수의 재귀함수//
obj2의 요소를 전부 다 재 할당을 해주고 있다!
그래서 obj와 obj2와 겉 모습은 똑 같지만 다른 데이터 주소를 가지고 있다고 볼 수 있다. 그래서 obj2 나 obj의 요소에 대한 값을 재 할당해도 같이 바뀌는 일이 없다.
알게된 점
깊은 복사가 어떤 알고리즘을 통해서 성사되는지 알 수 있었다.(모든 요소의 재 할당)
깊은 복사의 알고리즘을 이해했다.
for in의 객체요소의 반복에 대해서 더 잘 이해할 수 있었다.
'T.I.L' 카테고리의 다른 글
23-05-29 T.I.L 바닐라 자바스크립트 append() 2 (0) | 2023.05.29 |
---|---|
23-05-28 T.I.L 바닐라 자바스크립트 append() (0) | 2023.05.28 |
23-05-25 T.I.L 비동기 작업의 동기적 표현 Promise + Async/await 로직 해석(콜백함수) (0) | 2023.05.25 |
23-05-23 T.I.L 문자열 내 마음대로 정렬하기 (programmers) (0) | 2023.05.23 |
23-05-23 T.I.L 문자열 내 개수 비교 (programmers) (0) | 2023.05.23 |