[JS] 얕은복사, 깊은복사

GDORI·2024년 8월 17일
0

JavaScript

목록 보기
20/28

[JS] 데이터 타입 심화

위 게시글에서 공부했던 내용 중 얕은복사와 깊은복사에 대한 내용이 있는데, 튜터님께서 structuredClone 이라는 built-in deep clone 함수가 있다고 알려주셔서 알아보았다.

아래 내용은 위의 게시글에서 발췌했다.

불변객체에 대한 복사

위와 같이 하나하나 수작업으로 할 수는 없고, for..in 문으로 하나씩 꺼내어 복사하는 방법을 사용해야 한다.
다만 객체 안에 객체가 있는 경우를 대비하여 얕은 복사와 깊은 복사가 있다.
1. 얕은 복사

  • 전개연산자를 사용한 객체 복사 방법.
const copyObj = {...origin}
  • 함수를 이용한 객체 복사 방법
var copyObj = function (target) {
	var res = {};
	for (var idx in target) {
		res[idx] = target[idx];
	}
	return res;
}

객체 안에 객체가 있는 경우에는 완벽한 복사가 진행되지 않는다.
일반 값이 아닌 값(객체 등)은 참조로 처리되기 때문에 원본의 데이터를 보존할 수 없다.

  • 적용
var human = {
    fullname: 'gdori',
    friend: {
        fullname: 'gsooni'    
    }
}
const human2 = {...human};
human2.fullname = "hodori";
console.log(human2.fullname); // hodori

human2.friend.fullname = "hosooni";
console.log(human.friend.fullname); // hosooni
console.log(human2.friend.fullname); // hosooni

완벽한 복사가 이뤄지지 않은 상태에서 human2 객체의 friend 의 네임을 바꾸니
원본인 humanfriend 이름도 바뀐걸 알 수 있다.

  1. 깊은 복사
  • JSON을 활용한 객체 깊은 복사 방법
const deepCopy = JSON.parse(JSON.stringify(origin))

JSON.stringify() 는 객체를 JSON 문자열로 변환시킨다.
JSON.parse 는 JSON 문자열 구문을 분석하고 객체로 반환한다.
이 두가지를 이용하여 새로운 객체로 복사할 수 있다.

  • 재귀함수를 이용한 객체 깊은 복사 방법
var deepCopy = function(target) {
	var res = {};
	if (typeof target === 'object' && target !== null) {
		for (var idx in target) {
			res[idx] = deepCopy(target[idx]);
		}
	} else {
		res = target;
	}
	return res;
}

위 코드와 같이 한줄씩 요소를 뽑았을 때 object인 경우에 재귀하여 함수를 실행하고 아닌 경우(기본형 데이터)에는 일반적인 복사를 진행한다.

  • 적용
var human = {
    fullname: 'gdori',
    friend: {
        fullname: 'gsooni'    
    }
}

var deepCopy = function(target) {
	var res = {};
	if (typeof target === 'object' && target !== null) {
		for (var idx in target) {
			res[idx] = deepCopy(target[idx]);
		}
	} else {
		res = target;
	}
	return res;
}
const human2 = deepCopy(human);
human2.fullname = "hodori";
console.log(human2.fullname); // hodori

human2.friend.fullname = "hosooni";
console.log(human.friend.fullname); // gsooni
console.log(human2.friend.fullname); // hosooni

깊은 복사로 인하여 gdori의 친구가 지켜진 것을 확인할 수 있다.
원래 참조한 게시글을 썼을 당시에만해도 이정도 알고 있었고 복잡했다.
튜터님이 알려주신 방법을 사용해보자.

structuredClone

const deepCopy = structuredClone(origin);
  • 적용
var human = {
    fullname: 'gdori',
    friend: {
        fullname: 'gsooni'    
    }
}


const human2 = structuredClone(human);
human2.fullname = "hodori";
console.log(human2.fullname); // hodori

human2.friend.fullname = "hosooni";
console.log(human.friend.fullname); // gsooni
console.log(human2.friend.fullname); // hosooni

오.. 간편하다.
짧고 유용하다..
위에서 공부했던 방식들의 구조적인 단점을 해결한 방식이라고 하지만, 몇 가지 제한사항이 있다고 한다.

제한사항

  • 함수 : 객체 내 함수 폐기
  • 복제 불가 : 일부 값, 특히 Error와 DOM 노드는 구조화된 복제가 불가

결론

간편하고 짧은 방식을 채택하는 것이 효율적이긴 하겠지만 상황에 따라 여러 방식을 이용할 수 있어야 할 것 같다.
배울게 너무나도 많다..😂

(참조)
구조화된 Clone을 사용하여 자바스크립트 딥 복사

profile
하루 최소 1시간이라도 공부하자..

0개의 댓글