[JS] Data Type

돗개·2022년 6월 5일
0

crack JavaScript

목록 보기
4/18
post-thumbnail

Intro

자바스크립트의 모든 값은 데이터 타입(= 값의 종류)을 갖는다.
원시타입(primitive type)객체타입(object/reference type)으로 나뉜다.

데이터 타입의 필요성

  • 값을 저장할 때 확보해야 하는 메모리 공간의 크기를 결정하기 위해
  • 값을 참조할 때 한 번에 읽어 들여야 할 메모리 공간의 크기를 결정하기 위해
  • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해

1. 원시타입(primitive type)

변경 불가능한 값(immutablle value)으로, 한번 생성된 원시 값은 읽기 전용 값으로서 변경할 수 없다.

  • 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다.
  • 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다. (= 값에 의한 전달. pass by value)
  • 데이터의 신뢰성을 보장.
  • 원시 값을 갖는 변수에 새 원시 값을 재할당하면,
    • 새로운 메모리 공간을 확보하고, 재할당한 원시 값을 저장.
    • 변수는 새롭게 재할당한 원시 값을 가리킴. (= 변수가 참조하던 메모리 공간의 주소 변경)

immutable example)

let a = 100;
let b = a;
b = 200;
console.log(a);  // 100
console.log(b);  // 200

즉, 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값.
어느 한 쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다!
(*원시 값 자체를 변경할 수 없다는 것이지, 변수는 언제든지 재할당을 통해 변수 값을 교체할 수 있다.)


1) Number

정수, 실수와 상관 없이 하나의 숫자 타입만 존재.

  • 자바스크립트는 2, 8, 16 진수를 표현하는 데이터 타입이 없어서 해당 값을 참조하면 모두 10진수로 해석됨.
  • 모든 수를 실수로 처리하므로, 정수끼리 나누더라도 실수가 나올 수 있음.
  • 아래와 같이 특별한 값도 숫자 타입.
    • Infinity (양의 무한대)
    • -Infinity (음의 무한대)
    • NaN (not a number: 산술 연산 불가)
      • 1 * 'String'

2) String

텍스트 데이터로 작은/큰 따옴표 또는 백틱으로 텍스트를 감싼다.

  • 일반 문자열 내에서 줄바꿈 등의 공백을 표현하려면 이스케이프 시퀀스를 사용.
    • 템플릿 리터럴 내에서는 공백과 줄바꿈 그대로 표현됨.
  • 피연산자가 하나 이상 문자열인 경우 + 연산자를 통해 문자열을 연결.
    • 템플릿 리터럴에서는 표현식 삽입으로 간편히 문자열 조합.
// 1) using escape sequence and +
let name = 'suhyeon';
const text = 'hi.\nI\'m' + name;
console.log(text);
// hi.
// I'm suhyeon.

// 2) using template literal
const template = `
  hi.
  I'm ${name}.
`;
  • 문자열은 유사 배열 객체이면서 iterable이므로 배열과 유사하게 각 문자에 접근 가능.
    • 유사 배열 객체: 배열처럼 인덱스로 값에 접근 가능하며, length 속성을 갖는 객체.
    • 하지만, 문자열은 원시 값이므로 값을 변경할 수 없다.
const str = 'hello';
console.log(str[0]); // h
console.log(str.length); // 5

str[0] = 'H';
console.log(str); // hello

3) Boolean

논리적 참/거짓을 나타내는 truefalse으로, 조건문에서 자주 사용.


4) undefined

자바스크립트 엔진이 변수를 초기화할 때 사용하는 값.

  • 변수 선언 이후 값을 할당하지 않은 변수를 참조하면 undefined 반환.
  • 의도적으로 undefined를 할당하는 것은 권장하지 않음.
    • 변수에 값이 없다는 것을 명시하고 싶을 때는 null을 할당.
const foo;
console.log(foo); // undefined

5) null

변수에 값이 없다는 것을 의도적으로 명시.
변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미.

(* 함수가 유효한 값을 반환할 수 없는 경우, null을 반환하기도 함.)

6) Symbol

ES6에서 추가된 값으로, 다른 값과 중복되지 않는 유일무이한 값.
이름 충돌 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용.

const key = Symbol('key');
console.log(typeof key); // symbol
const obj = {};
obj[key] = 'value';
console.log(obj[key]); // value

2. 객체 타입(object/reference type)

변경 가능한 값(mutable value)으로, 재할당 없이 프로퍼티를 동적으로 추가/갱신/삭제할 수 있다.

  • 객체를 할당한 변수의 메모리 주소를 통해 메모리 공간에 접근하면, 참조 값(reference value)에 접근할 수 있다. (= 참조에 의한 전달)
    • 참조 값: 객체가 저장된 메모리 공간의 주소.
    • "변수는 객체를 참조하고/가리키고 있다." <-- 라고 표현
  • 객체는 크기를 미리 가늠하기 어렵기 때문에 생성/관리하는데 비용이 많이 들어 메모리의 효율적 소비가 어렵다. => 따라서, 객체를 복사하지 않고 변경 가능한 값으로 설계되어 있는 것이다!
  • 단점: 여러 개의 식별자가 하나의 객체를 공유할 수 있다.
const person = {
  name: 'suu'
};
person.name = 'kim';
person.address = 'seoul';
console.log(person); // {name: 'kim', address: 'seoul'}

얕은 복사 vs 깊은 복사

  • 공통점: 얕은 복사와 깊은 복사로 생성된 객체는 원본과는 다른 객체.
  • 얕은 복사: 객체에 중첩되어 있는 객체의 경우 참조 값을 복사.
  • 깊은 복사: 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 많듦.
const obj = { x: {y: 1} };
// shallow copy
const shallowObj = { ...obj };
console.log(obj === shallowObj); // false
console.log(obj.x === shallowObj.x); // true

// deep copy
const _ = require('loadash');
const deepObj = _.cloneDeep(obj);
console.log(obj === deepObj); // false
console.log(obj.x === deepObj); // false

3. 동적 타이핑(dynamic typing)

자바스크립트의 변수는 데이터 타입을 가지는게 아니라, 할당에 의해 타입이 결정된다.
재할당에 의해 변수의 타입이 언제든지 동적으로 변할 수 있다. (= 동적 타이핑)

  • 정적 타입
    • 변수 선언 시, 데이터 타입을 사전 선언. (= 명시적 타입 선언)
    • 변수의 타입을 변경할 수 없으며, 컴파일 시점에 타입 체크.
    • ex) C, C++, Java, Kotlin, Go, Rust, Scala
  • 동적 타입
    • 변수 선언이 아닌, 할당에 의해 타입이 결정됨. (= 타입 추론)
      • 즉, 값이 타입을 가지는 것으로, 현재 변수에 할당되어 있는 값에 의해 변수의 타입이 결정된다.
    • 재할당에 의해 변수 타입이 동적으로 변함. (= 동적 타이핑)
    • ex) JavaScript, Python, PHP, Ruby
    • 단점: 변수의 값을 확인하기 전에는 타입을 확신할 수 없으며, 의도와 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되기도 함.

*참고: 모던 자바스크립트 deep dive

profile
울보 개발자(멍.. 하고 울어요)

0개의 댓글