얕은 복사와 깊은 복사

정수·2023년 3월 6일
0

JavaScript

목록 보기
3/15
post-thumbnail

얕은 복사와 깊은 복사

우선 코드부터 확인해보겠습니다.

var user = {
	name: 'Jungsoo',
	urls: {
		naver: 'https://naver.com',
		insta: 'https://insta.com'
	}
}; // 객체 정의

var copyObject = function(target){
	var result = [];
	for (var prop in target) {
		result[prop] = target[prop];
	}
	return result;
}; // 객체 복사 함수 생성

var user2 = copyObject(user); // 객체 복사

user2.name = 'Jung';  // 기본형 타입 프로퍼티 변경
console.log(user.name === user2.name); // false, 불변성 성립

user2.urls.naver = 'https://www.naver.com'; // 참조형 타입 프로퍼티 변경
console.log(user.urls.naver === user2.urls.naver); // true, 불변성 성립 X

한 단계 더 들어간 urls의 내부 프로퍼티들은 기존 데이터를 그대로 참조하는 현상이 발생합니다.
이와 같이 바로 아래 단계의 값만 복사하는 것을 얕은 복사(shallow copy)라고 합니다.
이는 깊은 단계의 참조형 데이터를 복사할 때 불변성이 지켜지지 않습니다.

var user2 = copyObject(user); // 객체 복사
user2.urls = copyObject(user.urls); // 참조형 타입 복사

user2.urls.naver = 'https://www.naver.com'; // 참조형 타입 프로퍼티 변경
console.log(user.urls.naver === user2.urls.naver) // false, 불변성 성립

이처럼 참조형 데이터는 그 내부 프로퍼티들을 다시 복사해야합니다.
이를 재귀적으로 처리하면 아래와 같이 작성할 수 있습니다.

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;
}

typeof 명령어는 null 값에 대해서도 object 를 반환하는 버그가 있기에
object 임을 확인하는 동시에 null 이 아닌지도 확인해야 합니다.

이처럼 내부의 모든 값을 하나하나 찾아서 복사하는 것을 깊은 복사(deep copy)라고 합니다.
또한 JSON으로 변환 후 복사를 진행해도 깊은 복사가 가능합니다.

var copyObjectViaJSON = function(target){
	return JSON.parse(JSON.stringify(target));
}

다만 메서드(함수), __prote__, getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티들을 모두 무시하기 때문에 순수한 정보만 다룰 때 이용하면 좋습니다.

profile
해피한하루

0개의 댓글