[Core JavaScript] 데이터 타입

rami·2021년 8월 9일
0

core-java-script

목록 보기
1/1
post-thumbnail

🔷 데이터 타입의 종류

  • 기본형(Primitive type): 값이 담긴 주솟값을 바로 복제
    • Number
    • String
    • Boolean
    • null
    • undefined
    • Symbol (ES6에서 추가)
  • 참조형(Reference type): 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제
    • Object
      • Array
      • Function
      • Date
      • RegExp
      • Map, WeakMap (ES6에서 추가)
      • Set, WeakSet (ES6에서 추가)

🔷 데이터 타입에 관한 배경지식

🔹 메모리와 데이터

  • 비트
    • 0 또는 1만 표현할 수 있는 하나의 메모리 조각
    • 고유한 식별자를 통해 위치를 확인함
  • 바이트
    • 8개의 비트로 구성
    • 1바이트는 총 256(2의 8승)개의 값을 표현함
    • 메모리 주소값(시작하는 비트의 식별자)로 위치를 파악함

🔹 식별자와 변수

  • 변수(Variable)
    • 변할 수 있는 데이터(숫자, 문자열, 객체, 배열 등)
  • 식별자(Identifier)
    • 변수명(어떤 데이터를 식별하는 데 사용하는 이름)

🔷 변수 선언과 데이터 할당

🔹 변수 선언

자바스크립트 엔진은 메모리에서 비어있는 공간을 확보하고, 그 공간의 이름을 설정한다.

var a;  // 변할 수 있는 데이터를 만들고, 이 데이터의 식별자는 a로 한다.

🔹 데이터 할당

별도의 메모리 공간을 확보해서 문자열 데이터를 저장하고, 그 주소를 식별자를 검색해서 데이터 값에 저장한다.

var a;           // 변수 a 선언
a = 'abc';       // 변수 a에 데이터 할당

var a = 'abc';   // 변수 선언과 할당을 한 문장으로 표현

효율적인 처리를 위해 변수와 데이터를 별도의 공간에 나누어 저장한다.

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

🔹 불변값

  • 변수 영역의 변경 가능성
    • 바꿀 수 있으면 변수(Variable)
    • 바꿀 수 없으면 상수(Constant)
  • 데이터 영역의 변경 가능성
    • 한 번 만든 값은 바꿀 수 없고, 변경은 새로 만드는 동작을 통해서만 이뤄지는 기본형 데이터들이 불변값
var a = 'abc';  // 변수 a에 문자열 'abc'를 할당
a = a + 'def';  // 새로운 문자열 'abcdef'를 만들어 그 주소를 변수 a에 저장

var b = 5;      // 변수 b에 숫자 5를 할당
var c = 5;      // 데이터 영역에서 5를 찾아서 그 주소를 재활용하여 변수 c에 저장
b = 7;          // 기존에 저장했던 7을 찾아서 있으면 재활용하고, 없으면 새로 만들어서 b에 저장

🔹 가변값

'객체의 변수(프로퍼티) 영역'이 별도로 존재

var obj1 = {
  a: 1,
  b: 'bbb'
};

변수 영역은 변하지 않고, 기존 객체 내부의 값만 변경

var obj1 = {
  a: 1,
  b: 'bbb'
};
obj1.a = 2;

중첩 객체(nested object): 참조형 데이터의 프로퍼티에 다시 참조형 데이터를 할당

var obj1 = {
  x: 3,
  arr: [ 3, 4, 5 ]
};

더 이상 자신의 주소를 참조하지 않는 경우 참조 카운트가 0이 되고, 해당하는 메모리 주소는 가비지 컬렉터의 수거 대상이 되어서 런타임 환경에 따라 특정 시점이나 메모리 사용량이 포화 상태에 임박할 때 마다 자동으로 수거된다.

🔹 변수 복사 비교

기본형 데이터와 참조형 데이터의 변수 복사 과정은 동일하지만
데이터 할당 과정에서 이미 차이가 있기 때문에 변수 복사 이후의 동작에 큰 차이가 발생한다.

  • 기본형 데이터는 객체의 프로퍼티 변경 시 값이 달라진다.
  • 참조형 데이터는 객체의 프로퍼티 변경 시 값이 달라지지 않으나, 객체 자체를 변경했을 때는 값이 달라진다.
var a = 10;
var b = a;

var obj1 = { c: 10, d: 'ddd' };
var obj2 = obj1;

🔷 불변 객체(immutable object)

🔹 불변 객체를 만드는 간단한 방법

값으로 전달받은 객체에 변경을 가하더라도 원본 객체는 변하지 않아야 하는 경우에 불변 객체가 필요

// 객체의 가변성에 따른 문제점
var user = {
  name: 'Rami',
  gender: 'female'
};

var changeName = function (user, newName) {
  var newUser = user;
  newUser.name = newName;
  return newUser;
};

var user2 = changeName(user, 'Jung');

if (user !== user2) {
  console.log('유저 정보가 변경되었습니다.');
}

console.log(user.name, user2.name);  // result: Jung Jung
console.log(user === user2);         // result: true

changeName 함수가 새로운 객체를 반환하도록 수정

// 객체의 가변성에 따른 문제점의 해결 방법
var changeName = function (user, newName) {
  return {
    name: newName,
    gender: user.gender
  };
};

copyObject 함수를 통해 간단하게 객체를 복사하고 내용을 수정

// 얕은 복사(기본 정보를 복사해서 새로운 객체를 반환하는 함수)
var copyObject = function (target) {
  var result = {};
  for (var prop in target) {
    result[prop] = target[prop];
  }
  return result;
};

🔹 얕은 복사와 깊은 복사

  • 얕은 복사(Shallow Copy)

    • 바로 아래 단계의 값만 복사하는 방법
    • 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사함
      • 기존 데이터를 그대로 참조(해당 프로퍼티에 대해 원본과 사본이 모두 동일한 참조형 데이터의 주소를 가리킴)
  • 깊은 복사(Deep Copy)

    • 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법
// 객체의 깊은 복사를 수행하는 범용 함수
var copyObjectDeep = function (target) {
  var result = {};
  if (typeof target === 'object' && target !== null) {
    for (var prop in target) {
      result[prop] = copyObjectDeep(target[prop]);
    }
  } else {
    result = target;
  }
  
  return result;
};
// JSON을 활용한 간단한 깊은 복사
var copyObjectViaJSON = function (target) {
  return JSON.parse(JSON.stringify(target));
};

🔷 undefined와 null

  • undefined
    • 사용자가 명시적으로 지정할 수도 있지만 값이 존재하지 않을 때 자바스크립트 엔진이 자동으로 부여하는 경우가 있음
      1. 값을 대입하지 않은 변수(데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때)
      2. 객체 내부의 존재하지 않은 프로퍼티에 접근하려고 할 때
      3. return 문이 없거나 호출되지 않는 함수의 실행 결과
// (1) 값을 대입하지 않은 변수에 접근
var a;
console.log(a);  // result: undefined 

// (2) 존재하지 않는 프로퍼티에 접근
var obj = { a:1 };
console.log(obj.a);  // result: 1
console.log(obj.b);  // result: undefined 

// (3) 반환 값이 없으면 undefined를 반환한 것으로 간주
var func = function() { };
var c = func();  
console.log(c);  // result: undefined
  • null
    • 사용자가 명시적으로 '비어있음'을 나타내고 싶을 때 사용
var n = null;

// typeof null이 object라는 자바스크립트 자체 버그 주의
console.log(typeof n);  // result: object

// 동등 연산자(equality operator)로 비교할 경우 null과 undefined가 서로 같다고 판단
console.log(n == undefined); // result: true
console.log(n == null);  // result: true

// 일치 연산자(identity operator)를 써야만 정확히 판별 가능
console.log(n === undefined); // result: false
console.log(n === null);  // result: true

🔷 정리

데이터 타입

  • 기본형 → 불변값
  • 참조형 → 가변값

변수: 변경 가능한 데이터가 담길 수 있는 공간
식별자: 그 변수의 이름

변수 선언 동작 원리
1. 메모리의 빈 공간에 식별자를 저장
2. 그 공간에 자동으로 undefined 할당
3. 변수에 데이터 할당시
3.1. (기본형 데이터인 경우)
3.1.1. 별도의 공간에 데이터를 저장
3.1.2. 그 공간의 주소를 변수의 값 영역에 할당
3.2. (참조형 데이터인 경우)
3.2.1. 참조형 데이터 내부 프로퍼티들을 위한 변수 영역을 별도로 확보해서 확보된 주소를 변수에 연결
3.2.2. 앞서 확보한 변수 영역에 각 프로퍼티의 식별자를 저장
3.2.3. 각 데이터를 별도의 공간에 저장해서 그 주소를 식별자들과 매칭

참조형 데이터를 불변값으로 사용 하는 방법

  • 깊은 복사: 내부 프로퍼티들을 일일이 복사
  • 라이브러리 사용

'없음'을 나타내는 값

  • undefined: 어떤 변수에 값이 존재하지 않을 경우
  • null: 사용자가 명시적으로 '없음'을 표현하기 위해 대입한 값
profile
Developer

0개의 댓글