참조와 참조관계, 객체 복사방법

얕은 복사 : 참조

깊은 복사 : 복사

객체의 경우 그 값을 복사해서 원래의 값을 조작할 수 있다.

  1. 배열

var 과일 = [사과,딸기,오렌지];
var 복사 = 과일;

복사[0] = 포도;
과일 = [포도,딸기,오렌지];

2. 함수

var 함수 = function(){};
var 복사 = 함수;

함수.abc = 'abc';
복사.abc = 'abc';

복사.abc = 'def';
함수.abc = 'def';

원래 객체의 값에 영향을 주지 않고 복사하는 방법

  1. 원시데이터형으로 값을 복사한다.

var obj = {a: 1, b:2}
var obj2 = {};//빈 객체를 만든다.

obj2.a = obj.a;//1
obj2.b = obj.b;//2

obj2.a = 3;
obj.a = 1;//값이 변하지 않고 그대로다.

2. Object.keysforEach를 이용한다.

Object.keys(객체명) 을 하면 해당 객체의 key값을 배열로 바꾼다.

var obj = {a: 1, b:2, c:3,};
var obj2 = {};
Object.keys(obj);

Object.keys(obj).forEach(function(key) {
    obj2[key] = obj[key];
});
obj2.a = 4;
obj.a = 1;//값이 변하지 않고 그대로다.

Object.keysforEach를 이용할 때 주의점

var obj = {a: 1, b: { c:3},};//b는 다른 객체를 갖는다
var obj2 = {};
Object.keys(obj);

Object.keys(obj).forEach(function(key) {
    obj2[key] = obj[key];
});
obj2.a = 4;
obj.a = 1;//값이 변하지 않고 그대로다.
obj2.b.c = 8;
obj.b.c = 8;//값이 바뀌어버렸다.

원인을 분석하자면, 객체의 키(속성)값과 vlaue를 복사할 때 b는 객체를 담고 있기 때문에 복사를 할 때 객체가 복사되어 참조된 것이다.

3. slice() 를 이용한 복사

아래 코드는 slice를 사용하여 배열을 깊은복사하는 방법이다. 하지만 이 방법도 껍데기만 깊은 복사이고 속은 얕은 복사이다. Object.key와 forEach문을 이용했을 때와 비슷하다.

arr = [1,2,3];
arr2 = arr.slice();//참조관계를 끊으며 복사.
var obj3 = JSON.parse(JSON.stringify(obj1));//복사
var arr3 = JSON.parse(JSON.stringify(arr));//복사

2번과 3번은 객체들이 1단 데이터를 가질 때 사용한다. 객체 안에 객체가 있다면 이것은 3단계이다. var o = {a:1, b:2, c : { d: {e:3 } } } , [1,2,3[1,5,[6,7,8] ] ].

하지만 JSON을 이용한 깊은 복사 방법은 성능이 최악이기 때문에 최대한 안 쓰는 것이 좋고, 이 또한 완벽한 복사는 아니다.

참조관계인지 확인하는 방법은 '==='연산자로 확인가능하며, 'true' 라면 참조관계인 것이다.

Last updated