🎯 1장의 목표
- 자바스크립트가 데이터를 처리하는 과정 이해하기
🖊️ 내용 정리
데이터 타입
- javascript에는 6개의 기본형 데이터와 1개의 참조형 데이터가 있다.
변수를 선언 및 할당: 메모리 영역에서 어떻게 동작하는지 이해하기
- 이러한 데이터를 저장하는 공간을 변수라고 하며, 이 데이터를 식별하기 위해 붙이는 이름(식별자)을 변수명이라고 한다.
- 변수를 선언할 경우 변수명과 데이터는 메모리에 저장된다.
메모리 짧게 이해하기
메모리의 한 조각을 비트라고 하며, 비트는 고유한 식별자를 가진다. 메모리 한 칸은 1byte(8bit)며, 바이트 또한 바이트가 가진 8비트 중 첫 번째 비트의 식별자(메모리 주소값)를 통해 구분할 수 있다.
(1) 기본형
- 변수의 선언
컴퓨터는 메모리에서 비어있는 공간을 확보하고 공간의 이름을 변수명으로 지정한다.
- 데이터 할당 및 재할당
저장하려는 데이터가 메모리 상에 존재하는지 찾는다. 존재한다면 해당 데이터의 주소를 변수 영역에 저장한다. 없다면 이 데이터를 저장하기 위한 별도의 공간을 확보한 뒤 데이터를 저장하고, 그 주소를 변수 영역에 저장한다. 데이터를 재할당할 때도 동일한 과정을 거친다. 이러한 과정에서 주소가 참조되지 않는 데이터들은 가비지 컬랙팅을 당한다.
데이터를 변수 영역에 직접 저장하지 않는 이유는?
데이터의 변환에 따른 메모리 관리를 효율적으로 하고, 중복되는 데이터에 대한 처리 효율을 높이기 위해서다.
- 변수 복사
메모리에서 비어있는 공간을 확보한 후 공간의 이름을 변수명으로 지정한다. 이후 복사하려는 변수의 이름을 검색해 저장되어 있는 주소를 찾아온 뒤 해당 값을 저장한다.
(2) 참조형
- 변수의 선언 및 할당
우선 기본형과 마찬가지로 빈 공간을 확보해 공간의 이름을 변수명으로 지정하여 변수를 선언한다. 이후에 참조형은 프로퍼티 이름을 저장하는 공간을 따로 마련한다. 그리고 이 영역의 주소를 데이터 영역에 저장한 후 변수명에 해당하는 공간에 이 주소를 저장한다. 이후 프로퍼티를 저장하는 공간에 프로퍼티의 이름으로 공간의 이름을 지정한다. - 프로퍼티 데이터 할당
프로퍼티에 들어갈 데이터가 이미 저장되어 있는지 찾아본 후 있으면 해당 데이터의 주소를 프로퍼티 이름에 해당하는 공간에 저장한다. 없다면 이 데이터를 저장하기 위한 별도의 공간을 확보한 뒤 데이터를 저장하고, 이 주소를 프로퍼티 이름에 해당하는 공간에 저장한다. 프로퍼티의 데이터를 재할당할 때도 동일한 과정을 거친다.
- 변수 복사
메모리에서 비어있는 공간을 확보한 후 공간의 이름을 변수명으로 지정한다. 이후 복사하려는 변수의 이름을 검색해 저장되어 있는 주소를 찾아온 뒤 해당 값을 저장한다.
기본형과 참조형의 차이: 불변성&가변셩
변수의 선언과 할당을 메모리 영역에서 살펴보았을 때 기본형 데이터는 변수에 새로운 기본형 데이터를 할당했을 때 변수 내부에 저장하고 있던 주소값이 변한다. 기본형 데이터는 메모리 상에 한 번 올라가면 변경되지 않기 때문에 새로운 데이터를 할당할 경우 새로운 데이터를 메모리 공간에 새롭게 올리고 이 주소를 변수에 저장하기 때문이다. 그래서 기본형 데이터는 변경되지 않는다해서 불변성을 띈다고도 한다.
참조형 데이터는 프로퍼티의 값을 변경하더라도 참조형 데이터의 프로퍼티 주소를 저장하고 변수의 값은 변경되지 않는다. 그래서 참조형 데이터는 기본형과 반대로 가변성을 띈다고 한다. 하지만 이 가변성은 참조형 데이터의 내부 프로퍼티를 변경할 때만 성립하고, 참조형 데이터 자체를 변경할 경우에는 성립하지 않는다.
불변 객체
참조형 데이터는 내부 프로퍼티를 변경할 때 가변성을 띈다. 그래서 참조형 데이터가 담긴 변수의 값을 복사해 새로운 변수에 저장한 뒤 내부 프로퍼티를 변경하면 원본 참조형 데이터의 내부 프로퍼티의 값 또한 바뀌어 버린다. 하지만 이럴 때 원본 참조형 데이터가 바뀌질 않길 바란다면 참조형 데이터를 복사하면서 새로운 객체를 불변 객체로 만들어야 한다.
불변 객체를 만드는 방법
새로운 객체에 원본 객체 속 바꾸고자 하는 값과 변경하지 않는 기존 값을 넣으면 된다. 이때 기존 값이 기본형 데이터일 경우에는 그대로 복사하고, 참조형 데이터일 경우에는 다시 그 내부 프로퍼티를 복사하면 된다. 이렇게 중첩된 프로퍼티를 모두 복사하는 것을 깊은 복사라고 한다.
var copyObject = function (target) {
var result = {};
if (typeof target === "object" && target != null) {
for (var prop in target) {
result[prop] = copyObject(target[prop]);
}
} else {
result = target;
}
return result;
};
이렇게 직접 함수를 만들어 불변 객체를 생성할 수도 있지만 javascript 라이브러리를 이용해 불변성을 지닌 별도의 데이터 타입과 그 에 따른 메소드를 사용할 수도 있다.
불변 객체를 만드는 또 다른 단순한 방법: JSON 이용하기
객체를 JSON 문법으로 표현된 문자열로 전환했다가 다시 JSON 객체를 만들어 객체를 복사할 수도 있지만, 함수나 숨겨진 프로퍼티처럼 JSON으로 변환할 수 없는 프로퍼티는 복사 시에 사라진다.
Undefined & Null
javascript에는 '비어있다', '없다'라는 뜻으로 undefined와 null을 사용할 수 있다. 둘 다 사용할 수 있는 값이지만 '현재 값이 없다는 의미'로 데이터 타입을 직접 넣어줄 때는 undefined보다 null이 더 적합하다.
javascript 엔진은 사용자가 제대로 지정되지 않는 값을 호출할 때 undefoned를 반환한다. 이때 반환하는 undefined는 사용자가 직접 넣은 undefined와는 다르게 동작해 혼란을 줄 수 있기 때문에 직접 undefined를 넣어 사용하는 건 지양해야 한다. javascript 엔진이 undefined를 반환하는 예시로는, 사용자가 값을 대입하지 않는 변수에 접근하거나, 존재하지 않는 객체 내부의 프로퍼티에 접근하거나, return문이 없거나 호출되지 않은 함수의 실행 결과를 요청하는 경우가 있다.
typeof Null == object?
null은 typeof null이 object이기 때문에 변수의 값이 null인지 판단할 때는 ===을 사용하자!
🤔 읽은 소감 & 떠오르는 생각
3년 전에 자바스크립트를 딥하게 공부해 보겠다고 사서 읽었지만 내용이 어려워서 제대로 이해하지 못하고 다시 책장에 박아놨던 책... 이번에는 다시 읽어서 내 것으로 소화해 보겠다는 마음으로 읽기 시작했다. 확실히 아직 나에게 어려운 내용이라 한 장 한 장 읽는데 시간이 너무 오래 걸린다. 개념 이해가 잘 안가서 건너뛰고 나중에 이해하기로 결심한 부분도 있다...일단 1장을 다 읽었는데 금방 까먹을 것 같다 ㅎㅎ 그래도 참조형 데이터가 왜 다르게 동작했는지 이해할 수 있어서 좋았다.
🔍 새로 알았거나 잘 이해되지 않는 내용
- Symbol
심볼은 유일한 식별자를 만들 때 사용된다.
const id1 = Symbol("id"); const id2 = Symbol("id"); id1 === id2 // false
- WeakMap, WeakSet
객체만 담을 수 있다. - 정적 타입 언어
자료형을 컴파일 시에 결정하는 언어다. 반대로, 동적 타입 언어는 런타임에 자료형이 결정된다. - 메모리 주솟값
메모리 한 칸은 1byte(8bit)의 크기를 갖고, 이 한 칸을 가르키는 주소를 말한다. 64bit 운영체제는 64bit(8byte)로 주소를 표현할 수 있다는 뜻이며, 최대로 264 byte 만큼의 크기의 메모리를 가질 수 있는 것이다. - 프로토타입 체이닝
상위 프로토타입을 타고 스캔하는 것을 프로토타입 체이닝이라고 한다.
📚 참고
- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Symbol
- https://it-eldorado.tistory.com/149
- https://velog.io/@jeanbaek/JavaScript-Map-WeakMap-Set-WeakSet
- https://itmining.tistory.com/65
- https://st-lab.tistory.com/198
- https://velog.io/@sik2/JS-CoreJavaScript-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B4%EB%8B%9DPrototype-Link-Prototype-Object