반응형

 

Javascript를 너무 무시했고, 간과했던 부분에서 오류가 나서

다시 한번 리마인드 하는 기분으로 정리해보려고 한다.

 

일단 Javascript 자료형 타입은

Primitive Type(원시 타입)과 Reference Type(참조 타입) 두 가지로 나뉜다. (아래부터 원시/참조 타입으로 명시)

 

 

원시 타입은

Number, String, Booleans, null, undefined을 원시 타입으로 정의한다.

참조 타입은

Object, Array, Function을 우리는 참조 타입으로 정의한다.

 

원시 타입과 참조 타입의 가장 큰 차이점은 무엇인가?

원시 타입은 특정 공간에 값이 저장되는 것이고

참조 타입은 특정 공간에 값이 저장되어져 있는 공간의 주소값이 저장된다.

 

원시 타입부터 예제로 살펴보자.

1
2
3
4
5
6
var num1 = 1;
var num2 = num1;
num2 = 2;
 
console.log(num1);  // 1
console.log(num2);  // 2
cs

num1 공간에 1이라는 값이 들어갔다.

그다음 num2 라는 공간에 num1의 값인 1이 들어갔다. (값이 복사되었다.)

num2 값을 2로 변경했다.

num1라는 공간과 num2라는 공간은 다른 공간이므로 우리가 생각한 대로 1과 2가 자연스럽게 출력하게 된다.

 

이번엔 참조 타입을 예제로 살펴보자.

1
2
3
4
5
6
7
8
9
var obj1 = {
  "index"1
};
 
var obj2 = obj1;
obj2.index = 2;
 
console.log(obj1);  // { index: 2 }
console.log(obj2);  // { index: 2 }
cs

obj1 공간에는 해당 객체( { "index" : 1 } )가 저장되어진 주소 값이 저장된다.

obj2 공간에는 obj1 객체가 저장되어진 주소 값이 복사된다.

 

결과적으로 obj1과 obj2가 같은 공간의 주소값을 가지고 있는 것이다.

그렇기 때문에 obj2의 index값을 변경하고 난 다음, 두 객체를 비교해보면 동일한 값이 출력되는 것을 알 수 있다.

 

 

대학교 때나 기초적인 프로그래밍을 공부해봤다면,

Call of Value vs Call of Reference 를 공부하면서 이 부분을 많이 접했을 것이다.

 

이제는 내가 간과했던 부분, 놓쳤던 부분에 대해서 예제로 살펴보자.ㅜ.ㅜ(실수하지 마세요.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var arr = [{
  "index"1,
  "name""kim"
}, {
  "index"2,
  "name""lee"
},{
  "index"3,
  "name""park"
},{
  "index"4,
  "name""choi"
},{
  "index"5,
  "name""yoon"
}];
 
 var temp = arr[4];
 arr[4].index = arr[0].index;
 arr[0].index = temp.index;
 
console.log(arr);
cs

객체로 이루어진 배열을 만들었다. (객체는 원시 타입이 아닌 참조 타입이라는 점을 생각하자.)

예제로 만든 객체는 index, name이라는 속성만 가지고 있지만,

내가 실제로 실수한 객체는 더 많은 속성을 가지고 있었다.

 

그때 index 값을 서로 swap 하고 싶었다.

예를 들어서, 0번째 객체의 index <===> 4번째 객체의 index를 바꾸고 싶었다.

 

이때 오류를 범했던 부분이,

18번째부터 20번째 라인을 실수를 범했다. 라인별로 설명해보겠다.

 

18번째 : arr[4]는 참조 타입으로 값이 저장된 공간의 주소 값이 저장되어있는데, 그 주소 값을 temp에 복사한 것이다.

 

19번째 : arr[0].index를 arr[4].index에 값을 복사했다. index는 숫자이기 때문에 원시 타입이다.

하지만 arr[4].index의 값이 변하면서, temp.index 값도 동일하게 변경되어버렸다.

그 이유는 계속 말하지만, temp와 arr[4]는 같은 곳의 주소 값을 가지고 있기 때문에 arr[4].index가 변경되면서 temp.index도 변경되었다.

 

20번째 : 위의 결과로 인해서, arr[4].index / temp.index 값이 arr[0].index 값인 1로 되어버렸기 때문에

자연스럽게 arr[0].index도 1이 되었다.

 

차라리, 배열의 객체 전부를 swap 했더라면 이런 오류를 범하지 않았겠지만

특정 속성 값만 변경하려고 했었기 때문에 "왜 이런 오류가 발생하는지?" 이해하고 찾아내는데 시간이 걸렸다.

 

이 글을 읽는 개발자는 이러한 실수를 안 해서, 아까운 시간을 낭비하지 않았으면 바람으로 작성했다.

 

반응형

+ Recent posts