스노우보드 참 좋아하는데 맨날 키보드 앞에만 있네

[JavaScript] 참조 복사와 값 복사 (얕은 복사와 깊은 복사) 본문

개발/Javascript

[JavaScript] 참조 복사와 값 복사 (얕은 복사와 깊은 복사)

워너-비 2017. 10. 31. 19:02

자바스크립트 참조 복사와 값 복사


 

 

자바스크립트에서 = 를 이용하여 객체를 복사하면 값을 복사하는게 아니라 그 값의 위치를 참조만 하게 된다.

한번 자세히 알아보도록 하자.

 

 

 

자료형의 값 복사(깊은 복사)


자바스크립트는 기본 자료형(숫자, 문자열, boolean)의 값을 복사할 때 값을 완전히 복사한다.

따라서 =을 이용하여 값 복사를 쉽게 할 수 있다.

아래는 깊은 복사 예제이다.

 

 

1
2
3
4
5
6
7
var originalValue = 100;
var newValue = originalValue;
 
originalValue = 200;
 
alert(originalValue);
alert(newValue);

 

위 소스코드 1열에서 originalValue에 100의 값이 들어가고, 2열에서 newValue에 100이라는 값이 복사되어,

아래 그림과 같이 두 개의 변수 Original value, New value는 완전히 독립적인 상태가 된다.

 

 

 

 

originalValue    100


 
newValue   100

 

 

 

 

이 상태에서 4열에 따라 originalValue의 값을 200으로 변경하면, originalValue 값만 200이 된다.

이렇게 두 변수가 완전히 독립성을 갖는 것을 '값 복사' 또는 '깊은 복사' 라고 한다.

값을 복사하고 변경했을 때, 다른 값에 전혀 영향을 주지 않는다.

 

 

 

 

originalValue    200


 
newValue   100

 

6,7열에 따라 각각 200, 100이 출력된다.

 

 

 

객체의 참조 복사(얕은 복사)


객체에 변수를 저장하면, 실제 값을 저장하는 것이 아니라 객체를 메모리 어딘가에 만들고, 객체의 참조(위치 값)를 저장하게 된다.

따라서 객체(배열 포함)의 경우 = 를 이용하여 복사하면, 참조 복사만 가능하다.

아래의 소스코드를 보자

 

1
2
3
4
5
6
7
var originalArray = [1234];
var newArray = originalArray;
 
originalArray[0] = 200;
 
alert(originalArray);
alert(newArray);

 

1열에서 배열 originalArray에 [1,2,3,4]를 저장하는 과정은 다음과 같다.

주소값 0x10에 [1,2,3,4]를 저장하고, 객체 originalArray는 '0x10' 위치를 참조.

 

originalArray    0x10   0x10


 
1




2
        3




4

 

 

 

 

이때 2열에 따라 참조되는 위치값 '0x10' 이 복사된다.

 

originalArray    0x10


 
newArray   0x10

 

 

 

 

 

 

4열에서 originalArray[0] = 200; 을 실행하면, 참조되는 위치 0x10의 값이 변경된다.

originalArray와 newArray는 같은 메모리 위치를 참조하게 된다.

따라서 두 배열은 독립적이지 않다. 이런 것을 '참조 복사' 혹은 '얕은 복사'라고 한다.

 

originalArray    0x10 0x10


    200
newArray   0x10
2
        3




4

 

 

 

 

6,7열에 따라 newArray[0]을 출력하면 둘다 200을 출력하게 된다.

 

 

 

객체의 깊은 복사


객체의 깊은 복사를 하기 위해서는 새로운 객체를 만들고, for in 반복문을 통해 원본 객체에 반복을 돌리며, 키와 값을 하나하나 옮겨야한다.

아래의 코드에서는 clone의 함수를 사용하였다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function clone(obj){
  var output = {};
  for(var i in obj){
    output[i] = obj[i];
  }
  return output;
}
 
var original = {a: 10, b: 20};    // 원본 객체
var referenced = original;       // 얕은 복사 객체
var cloned = clone(original);  // 깊은 복사 객체
 
original.a = 20;
 
alert(JSON.stringify(referenced, null2));
alert(JSON.stringify(cloned, null2));

 

clone 메서드를 사용하여, 객체의 속성을 하나씩 '값 복사'를 해주면, 개체의 깊은 복사를 할 수 있다.

 


 

끝.

 

Comments