어떤 프로그래밍 언어든 이해할 수 있는 데이터의 종류가 있습니다. 이러한 종류들을 데이터 타입이라고 하는데, 변수에 데이터를 저장할 때 이 데이터 타입의 종류와 차이를 아는 것은 매우 중요합니다.

레퍼런스(Reference)는 직역하면 참조라는 뜻이 됩니다. 변수를 생성하고 그 값을 지정해줄 때 다른 변수를 참조하는 경우가 있는데, 그 결과는 참조하는 변수가 어떤 데이터 타입인지에 따라 달라집니다.


#Data Type의 종류

데이터 타입에는 두가지 종류가 있습니다. Primitive Data Types와 Complex Data Types입니다.

Primitive는 말 그대로 "원초적인" 이란 뜻으로, Primitive Data Types는 원초적인 데이터 타입이란 뜻입니다. 무슨 뜻이냐면 단순히 해당되는 데이터 타입의 값"만"을 가지고 있는 타입이며, 다른 속성이나 함수가 포함되지 않은 데이터란 뜻입니다.

더 자세한 걸 예제로 알아보기 전에, 자바스크립트에는 4가지 Primitive Data Types가 있습니다.

  1. String: 텍스트 값. 따옴표로 지정되는 데이터
    -> 예) var car_name = "기아";

  2. Number: 숫자 값.
    -> 예) var car_year = 2017;

  3. Boolean: True(참) 혹은 False(거짓) 값.
    -> 예) var new_car = true;

  4. undefined: 아무 값이 지정 안됨.

String, Number, Boolean, undefined. 이 네가지는 모두 각각이 데이터 타입인데, Primitive Data Types 카테고리에 해당되는 데이터 타입들입니다.

Complex Data Types는 Primitive Data Types에 포함되지 않은 오브젝트(Object) 타입과 함수(Function) 타입의 두가지가 있습니다. 지난 포스팅에서 오브젝트에 대해 설명했는데, 오브젝트는 특정한 하나의 값만을 가지고 있는게 아니고 속성을 포함하고 있으며, 각 속성에 값이 지정되어 있습니다.

한가지 알아둘 점은 자바스크립트에서는 배열(array) 타입도 오브젝트 타입으로 간주됩니다.

#데이터 타입을 알아내는 법

자바스크립트의 typeof라는 기능을 사용하면 간단하게 알아낼 수 있습니다.

typeof "기아";
// 결과 -> "string"

typeof 2016;
// 결과 -> "number"

typeof "2016";
// 결과 -> "string". 숫자도 따옴표안에 쓰면 string 타입이 됨.

typeof true;
// 결과 -> "boolean"

typeof xyz;
// 결과 -> "undefined". xyz라는 변수에 아무 값을 지정하지 않았기 때문

var obj = {a: "apple", b: "banana"};
typeof obj;
// 결과 -> "object"
typeof obj.a;
// 결과 -> "string"

var obj2 = ["a","b"];
typeof obj2;
// 결과 -> "object"

typeof function testFunc() {};
// 결과 -> "function"

#변수 레퍼런스

우선 일반적인 하나의 변수를 다른 변수로 지정해주면 결과가 어떻게 되나 확인을 해보겠습니다.

var a = "apple";
console.log(a);
// 결과 -> apple

var b = "banana";
console.log(b);
// 결과 -> banana

a = b;
console.log(a);
// 결과 -> banana

b = "berry";
console.log(b);
// 결과 -> berry

console.log(a);
// 결과 -> banana

처음에 변수 a의 값은 "apple", b의 값은 "banana"로 지정을 해줬습니다. 그 후 a의 값을 b로 지정하면 a의 값이 b의 값인 "banana"로 변한 걸 알 수 있습니다.

하지만 그 후 b의 값을 "berry"로 바꿔준 후 다시 a의 값을 확인해보면 "berry"가 아니고 "banana"로 나타나는 것을 알 수 있습니다.

여기서 알 수 있는 건 "a = b" 라고 지정해주면 a는 b라는 변수와 연동 되는 것이 아니고, 그 당시에 b의 값이 지정되는 것이라는 걸 알 수 있습니다. 이유는 b의 값이 primitive data types의 하나인 string 데이터 타입이기 때문입니다.

그렇다면 오브젝트를 참조하면 어떻게되나 실험해보도록 하겠습니다.

var a = {name: "apple"};
console.log(a.name);
// 결과 -> apple

var b = {name: "banana"}
console.log(b.name);
// 결과 -> banana

a = b;
console.log(a.name);
// 결과 -> banana

b.name = "berry"
console.log(b.name);
// 결과 -> berry

console.log(a.name);
// 결과 -> berry

a.name = "mango"
console.log(a.name);
// 결과 -> mango

console.log(b.name);
// 결과 -> mango

결과에서 보이는 것처럼 변수 a를 오브젝트 변수인 b에 레퍼런스를 줬을 경우, b의 name 속성을 바꾸면 a의 name 속성도 바뀐 걸 알 수 있습니다. 이유는 a는 b의 특정한 '값'을 참조 한게 아니고 b라는 오브젝트 자체를 참조 한 것이기 때문에, b의 속성 값이 바뀌면 b와 연동이 되어있는 a는 b의 속성 값을 보여주게 되는 겁니다.

같은 이유로 a.name으로 name 속성을 바꾸는건 b의 name 속성을 바꿔주는 것이 되는 겁니다.

이게 Primitive Data Types를 참조하는 것과 Complex Data Types를 참조하는 것의 차이점입니다.

그럼 만약 변수 a에 변수 b에 저장되어 있는 오브젝트를 참조가 아니고 그대로 복사해오고 싶은 경우는 어떻게 하면 될까요? Object.assign()을 이용해주면 됩니다.

var a = {name: "apple"};
console.log(a.name);
// 결과 -> apple

var b = {name: "banana"};
console.log(b.name);
// 결과 -> banana

// assign함수는 target과 source 인풋이 필요함
// 타겟은 a, 소스는 b
a = Object.assign(a, b);
console.log(a.name);
// 결과 -> banana

b.name = "berry"
console.log(b.name);
// 결과 -> berry

console.log(a.name);
// 결과 -> banana

결과에서 알 수 있듯이 Object.assign() 함수를 이용해주면 오브젝트를 참조하는게 아니고 복사하게 됩니다. 그렇기 때문에 b의 name 속성을 바꿔도 a는 b라는 오브젝트를 참조하고 있는게 아니고 b에 저장되어있던 오브젝트를 그대로 복사해 온 것이기 때문에, a의 name 속성에는 변화가 없는 것 입니다.