자바스크립트 입문_얕은복사와 깊은복사
자바스크립트 2021. 5. 3. 15:13(본 포스팅은 위키북스의 '코어자바스크립트' 책을 공부하면서 작성되었습니다_내돈내산)
- 얕은복사(shallow copy) : 바로 아래단계의 값만 복사하는 방법. 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다는 의미. 해당 프로퍼티에 대해 원본과 사본이 모두 동일한 참조형 데이터의 주소를 가리키게 됨.
- 깊은복사(deep copy) : 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법
<중첩된 객체에 대한 얕은 복사>
var copyObject = function(target) {
var result = {};
for (var prop in target){
result[prop] = target[prop];
}
return result;
};
var user = {
name : 'Jimin',
urls: {
portfolio : 'http://github.com/abc',
blog : 'http://blog.com',
facebook : 'http://facebook.com/abc',
}
};
var user2 = copyObject(user);
user2.name = 'Yu' ;
console.log(user.name === user2.name); //false
user.urls.portfolio = 'http://portfolio.com';
console.log(user.urls.portfolio === user2.urls.portfolio); // true
user2.urls.blog = '';
console.log(user.urls.blog === user2.urls.blog); // true
위에서 보면 첫번째 값이 false가 나오는것으로 보아 user2의 name 프로퍼티를 변경해도 user의 name 프로퍼티가 변경되지 않지만, 아래에서는 원본과 사본의 프로퍼티가 함께 변경되는것을 알 수 있음. (얕은복사를 진행한 경우 변경된 값만 주소값이 변경되었음)
>> user의 바로 아랫단계의 값은 변경되엇지만, 한단계 더 들어간 url의 내부 프로퍼티들은 기존 데이터를 그대로 참조하고 있음. 이러한 현상을 방지하기 위해 user.url 프로퍼티도 불변객체로 만들 필요가 있음.
<중첩된 객체에 대한 깊은 복사>
var copyObject = function(target) {
var result = {};
for (var prop in target){
result[prop] = target[prop];
}
return result;
};
var user = {
name : 'Jimin',
urls: {
portfolio : 'http://github.com/abc',
blog : 'http://blog.com',
facebook : 'http://facebook.com/abc',
}
};
var user2 = copyObject(user);
user2.urls = copyObject(user.urls);
user.urls.portfolio = 'http://portfolio.com';
console.log(user.urls.portfolio === user2.urls.portfolio); // false
user2.urls.blog = '';
console.log(user.urls.blog === user2.urls.blog) ; // false
!! 어떤 객체를 복사할 때 객체 내부의 모든 값을 복사해서 완전히 새로운 데이터를 만들고자 할 때, 객체의 프로퍼티 중에서 그 값이 기본형 데이터일 경우에는 그대로 복사하면 되지만, 참조형 데이터일경우는 그 내부의 프로퍼티까지 재귀적으로 복사를 수행해야만 깊은 복사가 이뤄지게 됨.
<객체의 깊은 복사를 수행하는 범용 함수>
var copyObjecDeep = function(target) {
var result = {};
if (typeof target === 'object' && target !== null){
for (var prop in target) {
result[prop] = copyObjecDeep(target[prop]);
};
}else {
result = target;
}
return result;
};
<JSON을 활용한 간단한 깊은 복사>
var copyObjectViaJSON = function(target){
return JSON.parse(JSON.stringify(target));
};
var obj = {
a: 1,
b: {
c: null,
d: [1,2],
func1 : function() {console.log(3);},
},
func2 : function() {console.log(4);},
};
var obj2 = copyObjectViaJSON(obj);
obj2.a = 3;
obj2.b.c = 4;
obj.b.d[1] = 3;
console.log(obj); // { a:1, b:{c:null, d:[1,3], func1:f(), func2:f()}}
console.log(obj2); // { a:3, b: {c:4, d: [1,2]}}
위의 방법은 객체를 JSON 문법으로 표현된 문자열로 전환햇다가 다시 JSON 객체로 바꾸는것.(전체가 다시 선언되는것과 동일한 효과를 가짐) 다만 함수나 getter/setter와 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시하게 됨.
'자바스크립트' 카테고리의 다른 글
자바스크립트 입문_스택(stack)과 큐(queue)(실행컨텍스트) (0) | 2021.05.03 |
---|---|
자바스크립트 입문_undefined와 null (0) | 2021.05.03 |
자바스크립트 입문_불변객체 (0) | 2021.05.03 |
자바스크립트 입문_변수의 복사 (0) | 2021.05.03 |
자바스크립트 입문_가변값 (0) | 2021.05.03 |