자바스크립트는 데이터를 어떻게 저장할까?

sudyn·2023년 7월 28일

JavaScript

목록 보기
1/14

데이터타입 (Data Type)

정의와 구분

데이터 타입은 프로그래밍 언어에서 사용할 수 있는 데이터의 종류를 말한다.
Javascript의 데이터 타입은 크게 두가지로 나뉜다 : 기본형, 참조형

  • 기본형 : Number, String, Boolean, null, undefined, Symbol
  • 참조형 : object(Map, Set), array, function, date, RegExp…

원시 타입(primitive type)

정의와 특징

원시타입의 값은 변경 불가능한 값 (immutable value)이다.
다시 말해 한 번 생성된 원시 값은 읽기 전용 (read-only)이며 call by value(값에 의한 전달)이다.

“원시 값은 변경 불가능하다”는 뜻은 원시 값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 뜻은 아니다. 변수는 언제든지 재할당을 통해 변수 값을 변경 할 수 있다.

  • 변수 : 값을 저장하기 위해 확보한 메모리 공간 자체로 식별자의 한 형태
  • 식별자 : 어떤 데이터를 식별하는데 사용하는 이름(=변수명)
  • : 변수에 저장된 데이터

변수 선언과 데이터 할당(메모리 저장방식)

let a; // a라는 변수를 선언 후 식별자를 a로 한다.
a = 10; // 변수 a에 10을 할당한다.

변수 공간과 값을 저장하는 데이터 공간을 나누어 생각해보자. 간략하게 메모리 구조를 작성하여 설명한다.

1) 변수를 저장하기 위한 빈 메모리공간(@1001)을 확보한다.
2) 이 변수의 식별자를 ‘a’로 한다.
3) 저장할 데이터인 10이 데이터 영역에 있는지 탐색한다. 10이 저장되어 있지 않다면 비어있는 데이터 영역의 빈 공간(@5014)에 10을 저장한다.

4) 변수 영역에서 식별자 ‘a’를 검색한다.(@1001)
5) 10을 저장한 데이터 영역의 주소(@5014)를 변수 a(@1001)의 값에 저장한다.

  • 왜 변수 영역에 직접 데이터를 저장하지 않을까?
    • 데이터 변환을 자유롭게 할 수 있다.
    • 메모리를 더욱 효율적으로 관리할 수 있다.
  • 문자열은 자바스크립트에서 메모리 공간이 가변적이다. 즉 문자열의 크기가 동적으로 변할 수 있다.

  • 문자열을 변경하는 경우 문자열의 크기가 더 커지는 경우에는 새로운 메모리 공간을 확보하고 데이터를 복사하는 작업이 필요하게 된다. 또한 문자열이 작아지는 경우에도 해당 부분을 제거하고 메모리를 해제하는 작업이 필요할 수 있다.

  • 이렇게 문자열을 빈번하게 조작하거나 문자열의 길이가 커질수록 성능에 영향을 미친다.

  • 따라서 데이터 공간과 변수 공간을 분리하여 새로운 메모리 공간을 할당하고 공간을 참조하는 방식으로 효율적으로 메모리를 관리할 수 있게 된다.

  • 그렇다면 재할당하게 되면 어떻게 될까?

let a = 10;
a = 20; // 재할당
a=

a = 20; 를 재할당할경우 데이터 공간 @5014의 값을 변경하면 되지 않을까? (10에서 20으로)

아니다!!!!!!!!!!

데이터 공간에 저장된 값은 바꿀 수 없다 ⇒ 불변성

1) 저장된 숫자 10는 그대로 두고(@5014) 새로운 메모리공간( @5015) 에 값 20을 저장한다.

2) 그리고 a에 저장된 메모리 주소의 값을 (@5014→ @5015)로 변경해준다.

→ 두 값(2,5)는 모두 메모리에 존재하며 변수가 가리키는 공간만 변경되는 것이다.

3) @5014에 저장된 값은 사용되지 않으므로 메모리낭비를 막기 위해 GC에 의해 제거된다.

가비지 컬렉터(Garbage Collector)
-
사용되지 않는 메모리를 자동으로 탐지해 해제하여 사용 가능한 메모리를 유지하는 역할

  • 애플리케이션의 성능과 메모리 관리를 효과적으로 지원해준다.
  • 그렇다면 이번에는 변수 b에 변수 a를 할당해보자.
let a = 2;
let b = a;
a = 5;

1) 하나의 변수 공간을 확보한 후 이름을 b로 지정한다.
2) b는 a와 같은 값을 가리킨다.
3) 변수 a에 값 5를 할당하면 a가 가리키는 주소값만 변경된다.

종류

number

숫자 타입을 처리하며, 모든 수를 실수(정수, 실수, 지수, NaN, Infinity 등)로 처리한다.

NaN(Not a Number) : 숫자가 아닌 값을 나타내는 값이다. 수학적으로 정의되지 않은 계산이나 숫자가 아닌 값을 숫자로 변환하려고 할 때 발생한다.
let num = ‘hello’ / 2;
console.log(num); // NaN;
console.log(type of num); // number; 타입은 number다.

String

문자열 타입으로 텍스트 데이터를 나타내는데 사용한다. 작은 따옴표(’ ‘), 큰따옴표(””) 안에 넣어 생성하며 일반적으로 작은따옴표 를 사용한다. 백틱(``)도 사용된다.
배열처럼 인덱스를 통해 접근할 수 있다. 이를 유사배열이라 한다.

1) 문자열 길이 확인 : str.length;
2) 문자열 결합, 검색, 대체 , 분할 등 메소드가 다양하다.

boolean

논리적 참, 거짓을 나타내는 ture, false 뿐이다.
참과 거짓으로 구분되므로 조건문(if, else, switch)과 논리연산자(&&, ||, !)와 함께 사용된다.
false로 간주되는 데이터 타입 : null, undefined, 숫자 0, 비어있는 문자열 → Falsy한 값

console.log(null);           // 출력: false
console.log(undefined);      // 출력: false
console.log(0);              // 출력: false
console.log('');             // 출력: false

undfined

undefined 타입의 값은 undefined가 유일하다
.
선언 이후 값을 할당하지 않은 변수는 undefined 값을 가진다. 즉 선언은 되었지만 값을 할당하지 않은 변수에 접근하거나 존재하지 않는 객체 프로퍼티에 접근할 경우 반환된다.
개발자가 의도적으로 값을 할당한 값이 아니라 자바스크립트 엔진에 의해 초기화된 값이다.

var foo;
console.log(foo); // undefined

null

null 타입의 값은 null 이 유일하다. 의도적으로 변수에 값이 없다는 것을 명시할 때 사용한다.
원시 값을 할당한 변수에 새로운 변수를 재할당하면 메모리 공간에 저장되어 있는 재할당 이전의 원시 값을 변경하는 것이 아니다. 새로운 값을 저장하기 위해 새로 메모리 공간을 확보하고 재할당한 원시값을 저장한다. 변수는 새롭게 재할당한 원시 값을 가리킨다.

  • typeof null // object인 것은 javascript 의 자체적 버그이다.

Symbol

ES6에서 새로 추가된 데이터 타입으로 변경 불가능한 원시 타입의 값이다. 주로 객체 속성의 키로 사용되어 이름 충돌을 방지하는 데에 활용된다.

참조 타입(Reference type)

정의와 특징

  • 객체(Object)라고도 불리며 객체, 배열, 함수 등이 포함됩니다.
  • Mutable 변경 가능한 값이다.
  • 해당 값에 대한 참조를 저장하고 변수는 실제 값을 직접 저장하는 것이 아닌 저장된 주소를 참조한다. (Call by Reference)
  • 따라서 참조 타입 변수 간에 값을 할당하면 주소가 복사되어 동일한 객체를 가리킵니다.

객체 선언과 데이터 할당

let obj1 = {
	name : '수진',
    like : '피자',
}

1) 먼저 변수 obj1를 저장할 빈 메모리 공간(@1001)을 할당하고 식별자로 obj1을 저장한다.

2) 이 프로퍼티로 이루어진 집합을 저장하기 위해 별도의 변수영역(@7001)을 확보하고 그 변수 영역의 주소(@7001~) 을 데이터 영역의 임의의 공간 @5014)에 저장한다.

3) 프로퍼티를 저장할 변수 영역의 주소(@7001~)을 담고 있는 데이터 영역의 주소(@5014)를 식별자가 obj1인 변수(@1001)의 값에 저장한다.

4) @5014의 변수영역에 확보된 변수영역(@7001, @7002)에 각각 식별자로 name, like를 저장한다.

5) 식별자가 a인 프로퍼티(@7001)에 할당할 데이터인 ‘수진’이 데이터 영역에 있는지 탐색한다.
없다면 데이터 영역의 임의의 공간 @5016에 ‘수진’을 저장하고 ‘수진을 저장한 메모리주소(@5016)를 식별자가 a인 프로퍼티(@7001)의 값에 저장한다.
업로드중..

6) 식별자 like인 프로퍼티(@7002)에 할당할 데이터 ‘피자’가 데이터 영역에 있는지 탐색한다.

없다면 데이터 영역의 임의의 공간 @5017에 ‘피자’을 저장하고 ‘피자’를 저장한 메모리주소(@5017)를 식별자가 like인 프로퍼티(@7002)의 값에 저장한다.

원시타입 데이터는 데이터 영역에 실제 값이 저장되고 참조타입 데이터는 데이터 영역에 값이 저장된 메모리 주소를** 저장한다.

정리하자면,

  • 원시타입 데이터는 불변성을 가지고 있어서 변수 값을 변경해도 원본 값은 변하지 않는다.
  • 참조타입 데이터는 변수들이 같은 객체를 참조하고 있기 때문에(불변성을 가지고 있지 않음) 한 변수가 변경되면 다른 변수에도 영향을 미칠 수 있다.

종류

객체

속성과 메소드를 가진다. 중괄호({})를 이용해 객체를 생성한다.

배열

여러개 의 데이터를 순서대로 저장하는 데이터 타입이다.

함수

재사용 가능한 코드 블록을 정의하는 데이터 타입

Map

key-value의 쌍으로 데이터를 저장한다. 키에 다양한 자료형을 허용한다.

Set

중복되지 않는 값들의 집합을 저장하는 데이터 타입이다.


Call by value vs Call by Reference

Call by Value (값에 의한 호출)

  • 원시타입의 데이터는 변수에 직접 값이 저장됩니다.
  • 함수에 원시타입 데이터를 인자로 전달할 때, 값이 복사되어 함수 내부로 전달됩니다.
  • 따라서 함수 내부에서 인자의 값이 변경되어도 원본 값은 변하지 않습니다.

Call by Reference (참조에 의한 호출)

실제로는 Call by Sharing이라고도 하는데, 값이 아니라 값이 저장된 메모리의 주소가 전달되기 때문입니다.

  • 참조타입의 데이터는 변수에 해당 데이터의 주소가 저장됩니다.
  • 함수에 참조타입 데이터를 인자로 전달할 때, 주소가 복사되어 함수 내부로 전달됩니다.
  • 따라서 함수 내부에서 인자의 값이 변경되면 원본 데이터도 함께 변경됩니다.

📖 참고

코어자바스크립트, 정재남
https://devowen.com/481
https://www.youtube.com/watch?v=tlF5eMAGATI&list=PLEOnZ6GeucBW11uFNvzxToKym9Zv74hxh&index=4
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
https://www.youtube.com/watch?v=hM8s3ZaycGk
https://cloer.tistory.com/27

profile
개발계발하는 프론트엔드 개발자🍠

1개의 댓글

comment-user-thumbnail
2023년 7월 28일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기