데이터 타입

yoo chang heon·2022년 4월 10일
0

JavaScript

목록 보기
6/9

데이터 타입

데이터 타입의 종류

기본형

  • 숫자형
  • 문자열
  • boolean
  • null
  • undefined
  • Symbol (ES6 추가)

특징

기본형은 할당이나 연산 시 주소값 복제
불변성

참조형

  • 객체
  • 배열
  • 함수
  • 날짜
  • 정규 표현식
  • Map
  • Set

특징

참조형은 할당이나 연산시 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값 복제

참고

C/C++, 자바 등의 정적 타입 언어는 메모리의 낭비를 최소화하기 위해 데이터 별로 할당할 메모리 영역을 정해놓음.(메모리 양이 부족했던 시절)
JS는 메모리 용량이 과거보다 커진 상황에서 등장했기 때문에 메모리 관리로부터 더 자유로움. => 메모리를 넉넉하게 할당
ex)
숫자: 64비트(8바이트)
문자열: 정해진 규격 없음( 가변적으로 )
모든 데이터는 메모리 주솟값을 통해 서로 구분하고 연결할 수 있다.

변수 선언과 데이터 할당

변수: 변할 수 있는 수(데이터), 변경 가능한 데이터가 담길 수 있는 공간
식별자: 변수명

변수 선언

변할 수 있는 데이터를 만든다 + 이 데이터의 식별자(변수명)을 정한다.
var a라는 명령을 받으면 컴퓨터는 메모리에서 비어있는 공간 하나를 확보하고, 이 공간의 이름(식별자)을 a라고 지정한다. 이후 a에 접근하고 싶으면 a라는 주소를 가진 이름을 검색해서 데이터를 반환한다.

데이터 할당

이제 a에 값을 할당하려 하면 할당하려는 값을 별도의 메모리 공간을 확보해서 할당하고, 그 주소를 a라는 이름을 가진 주소를 검색해서 넣어준다.
변수영역에서 빈공간 확보(1) + 공간 이름 지어준다. => 데이터 영역에 값을 넣는다.(2) => 2를 1에 넣는다.

왜??
데이터 변환을 자유롭게 할 수 있게 함과 동시에 메모리, 중복 데이터에 대한 처리를 더 효율적으로 관리할 수 있다.

기본형 데이터와 참조형 데이터

변수, 상수 구분=> 변수 영역 메모리
불변성 구분 => 데이터 영역 메모리
변경은 새로 만들어서만 가능 (변경하려는 값이 원래 있는지 보고 없으면 새로 만들어서 그 주소를 다시 넣어줌.)

불변값

변수와 상수를 구분 짓는 변경가능성의 대상은 변수 영역 메모리이다.(한번 할당이 일어난 공간에 재할당이 일어날 수 있는지)
한번 만든 값은 다른 값으로 변경할 수 없고, 변경은 새로 만드는 방법 밖에 없다.

가변값

참조형 값을 변수에 할당하면 기본형 데이터와 다르게 객체의 변수(프로퍼티)의 영역이 따로 존재한다는 것이다. 객체가 별도로 할애한 영역은 변수 영역일뿐 데이터 영역의 기존 메모리 공간은 그대로 활용하고 있다. 데이터 영역에 저장된 값은 모두 불변값이다.

참조가 되지 않는 것은 참조카운트를 세서 0이되면 GC가 수거한다.


추가(GC)

가비지 콜렉션 알고리즘의 핵심개념은 참조이다.

Reference-counting 가비지 콜렉션

더 이상 필요없는 오브젝트를 어떤 다른 오브젝트도 참조하지 않는 오브젝트라고 정의
이를 참조하는 다른 오브젝트가 하나도 없는 경우 수집한다.

한계(순환참조)

두 객체가 서로를 참조하는 속성으로 생성되어 순환 구조를 생성하면 함수 호출이 완료되고, 두 객체가 스코프를 벗어나도 계속해서 서로를 참조하고 있기 때문에 Reference-counting 가비지 콜렉션은 둘다 수거하지 않는다.
=> 메모리 누수의 흔한 원인.

function f() {
  var x = {};
  var y = {};
  x.a = y;         // x는 y를 참조한다.
  y.a = x;         // y는 x를 참조한다.

  return "azerty";
}

f();

Mark and Sweep 알고리즘

더 이상필요없는 오브젝트를 닿을 수 없는 오브젝트로 정의

root라는 오브젝트의 집합을 가지고 있다.( 전역변수들) 주기적으로 roots로 부터 시작해서 roots가 참조하는 오브젝트들, 이 오브젝트들이 참조하는 오브젝트들... 을 닿을 수 있는 오브젝트라고 표시한다. 이후 닿을 수 없는 오브젝트에 대한 가비지 콜렉션을 수행한다.

Reference-counting 알고리즘보다 효율적(참조되지 않는 오브젝트는 모두 닿을 수 없는 오브젝트지만 역은 성립 x, 반례: 순환참조하는 오브젝트)

한계(수동 메모리 해제)

어떤 메모리를 언제 해제할지에 대해 수동적으로 결정하는 것이 편리할 때가 있다. 수동으로 객체의 메모리를 해제하려면 객체 메모리에 도달할 수 없도록 명시하는 기능이 있어야한다.
현재의 JS에서는 명시적으로 가비지 컬렉션을 작동할 수 없다.

같이 보면 좋을 것 같은 글


변수의 복사 비교

복사를 했을 때 기본형, 참조형 모두 같은 주소를 바라보게 된다. but 데이터 할당과정이 다르기 때문에 변수 복사 이후 동작에서 차이가 일어난다.

기본형 복사 이후 값 변경: 값이 달라졌을 때 => 서로 다른 주소
참조형 복사 이후 값 변경: 값이 달라졌을 때 => 같은 객체를 보고 있음

엄밀히 말하면 모든 데이터 타입 변수에 할당하려면 주소값을 복사해야 하므로 참조형이다.
기본형은 주솟값 복사 한번
참조형은 기본형에 한단계를 더 거침(데이터 영역 주소 복사)

불변객체

내부 프로퍼티를 변경할 때마다 매번 새로운 객체를 만들어 재할당하는 것.
기존 데이터는 변하지 x

왜??
값으로 전달받은 객체에 변경을 가하더라도 원본객체는 변하지 않아야할 경우
모든 프로퍼티 복사해서 새로운 객체만들기
규칙을 따르지 않고 변경 못하게=> immutable.js, baobob.js

얕은 복사와 깊은 복사

  • 얕은 복사=> 바로 아래 단계의 값만 복사(주소만)=> 원본 사본이 모두 동일한 참조형 데이터 주소를 가리킴 => 한쪽에서 변경이 일어나면 다른 쪽도 변경이 일어남
  • 깊은 복사=> 내부의 모든 값들을 하나하나 찾아내서 전부 복사 => 아예 다 복사해서 새로운 객체를 만들어줌.=> 한쪽에서 변경이 일어나도 다른 쪽에 영향없음

깊은복사 간편 처리 방법: 복사할 객체 => JSON문자열=> JSON 객체

undefined와 null

undefined

값이 존재하지 않음, JS 엔진이 자동으로 부여해줌 (사용자가 어떤 값을 지정할 것이라고 예상하는 상황임에도 안했을 경우)

  1. 값 대입하지 않은 변수(데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근)
  2. 객체 내부 없는 프로퍼티에 접근
  3. return 문이 없거나 호출되지 않은 함수의 실행결과

비어있는 요소 !== undefined를 할당한 요소
비어있는 요소는 순회대상에서 제외
배열에서 특정 인덱스에 값을 지정할 때 비로소 공간 확보, 저장 값이 지정안 된 index는 아직 존재하지 않는 프로퍼티
undefined는 그 자체로 값. 비어있지만 하나의 값으로 동작함.(순회대상)
사용자가 값으로써 할당된 undefined는 실존하는 데이터지만 JS가 할당해주는 undefined와 혼돈을 피하기위해 사용 지양 => null 사용

null

비어있음을 명시적으로 사용

null의 typeof는 Object
동등 연산자로 비교하면 null== undefined이다. (비교하려면 === 사용)

0개의 댓글