최근 며칠간 자바스크립트의 데이터 타입에 대해 공부했습니다. 중요한 것은 공부를 한 것 자체가 아닌 공부한 것을 나의 것으로 흡수하였는지라고 생각하니다. 그래서 내가 잘 이해하였는지를 점검하기 위해 몇가지 핵심 질문들을 만들어봤습니다. 다음 질문에 대해 다른 사람에게 설명할 수 있는지 점검해보면 많은 도움이 될 것 같습니다.
좋은 참고서가 되어준 책, 코어자바스크립트
저는 코어자바스크립트라는 책을 중심으로 자바스크립트의 데이터 타입에 대해 공부하고, mdn이나 위키피디아등 다른 자료들을 참고했습니다. 그리고 위 질문에 대해 나름 답변을 적어보았습니다. 아직 제가 자료구조를 깊게 공부하지는 않아 조금은 추상적인 답변을 할 수도 있을텐데, 한달에 한번정도 이 질문에 다시 답해보며 점점 정교해지는 훈련을 하려 합니다.
기본형 데이터에는 String
, Number
, Boolean
, null
, undefined
, Symbol
이 포함되어 있고 참조형 데이터에는 Object
와 Array
, Function
, Map/WeakMap
, Set/WeakSet
, RegExp
, Date
이 포함되어 있습니다.
var a = "기본형";
위와 같은 코드가 있을 때 데이터가 메모리에 저장되는 과정은 다음과 같습니다.
var a = "기본형";
a = 123;
위와 같이 변수를 선언하고 값을 할당한 이후에 새로운 데이터를 재할당하는 과정은 아래와 같습니다.
var obj = {
a: "가나다",
b: 123,
}
var obj = {
a: "가나다",
b: 123,
}
obj.b = [1, 2, 3]
위와 같이 객체의 프로퍼티 데이터 값을 재할당하는 과정은 아래와 같습니다.
1. 메모리에 b를 선언합니다.
2. ...
메모리를 저장할 때 변수나 프로퍼티에 데이터를 통으로 저장하지 않고, 데이터를 저장한 메모리 주소를 할당하는 이유는 다음과 같은 장점이 있어서다.
var a = "afjsldkjflkasdjflkasdfjklsdajflkaljflkjdaslkfjalsdfjlasfdasklfj";
var b = a;
console.log(a === b);
// "afjsldkjflkasdjflkasdfjklsdajflkaljflkjdaslkfjalsdfjlasfdasklfj"를
// 이진수로 변환하여 하나하나 비교하는 것이 아닌 저장된 메모리주소가 같다는 것만 비교하면
// 연산을 적게 하면서 비교할 수 있다.
var a = "가나다";
var b = a;
b = 123;
console.log(a)//"가나다"
console.log(b)//123
기본형 데이터를 다른 변수에 복사할 때 메모리 주소를 할당한다. 그리고 복사한 변수에 다른 값을 재할당하면 메모리에 새로운 데이터 123을 저장한뒤 b에 123을 저장한 메모리 주소를 할당한다. 즉 기본형 데이터를 복사하고 복사한 변수의 데이터를 재할당했을 때 원본 값은 불변하다.
var obj1 = {
prop: "가나다";
}
var obj2 = obj;
obj2.prop = 123;
console.log(obj1.prop) // 123
console.log(obj2.prop) // 123
참조형 데이터는 복사한 후 프로퍼티를 바꿔도 객체의 메모리 주소는 그대로이기 때문에 원본 데이터까지 바뀐다(가변).
참조형 데이터를 불변하게 복사하기 위해서는 프로퍼티들의 주소가 저장된 메모리 주소를 복사하는 것이 아닌 아예 새로운 객체를 만들어야 한다. 예시 코드는 다음과 같다.
const copyObject = (obj) => {
const newObj = {}
for(const prop in obj) {
if(typeof obj[prop] === 'object' && typeof obj[prop] !== null) {
//현재 프로퍼티가 객체면 해당객체도 복사한다.
newObj[prop] = copyObject(obj[prop])
}else{
//현재 프로퍼티가 객체가 아니면 값만 복사한다.
newObj[prop] = obj[prop]
}
}
return newObj;
}
const obj = {
name: "kiki",
family: {
mom: {
name: "kuku",
},
dad: {
name: "kalkal",
},
}
}
const obj2 = copyObject(obj);
기본형 데이터: 메모리에 값을 재할당해도 기존 메모리의 데이터가 바뀌는 것이 아닌 새로운 데이터를 저장하여 주소만 바꾼다. 그리하여 불변한 특징을 갖고있다 할 수 있다.
참조형 데이터: 객체의 프로퍼티를 바꿨을 때 기존 메모리 주소를 유지하며 데이터를 바꾸기 때문에 가변하다고 할 수 있다.