그대는 원시타입인가, 참조타입인가?

전종훈입니다·2023년 5월 20일
4

JavaScript

목록 보기
1/2
post-thumbnail

오늘은 자바스크립트 Data Type에 대해서 알아보쟈!

Data Type?

❓ Data Type은 값의 종류다. 자바스크립트의 모든 값은 Data Type을 가진다
  • 자바스크립트에서 data type은 총 7가지 데이터 타입을 제공
  • 7개의 데이터 타입을 크게 2가지로 분류한다 → 원시 타입(primtive type) / 참조타입 or 객체타입 ( reference type / object type )

7가지 Data Type ⇒ 원시타입 / 참조타입

구분Data Type
원시숫자 ( number )
원시문자열 ( string )
원시불리언 ( boolean )
원시undefined
원시null
원시심벌 ( symbol )
참조객체, 함수, 배열 등

각 타입 특징에 대해서 알아보자

원시타입


number

  • 다른 언어같은 경우 정수, 실수 구분해서 타입지정 ( double, float 등 )
  • 자바스크립트는 number 하나만 존재
  • ECMAScript 사양에 따르면 숫자 타입의 값은 배정밀도 64비트 부동 소수점 형식 따른다고 한다 → 모두 실수로 처리한다는 말 → 정수를 위한 타입 별도 존재 X
  • 정수, 실수, 2진수,8진수 등 모든 리터럴들은 모두 메모리에 배정밀도 64비트 부동소수점 형식의 2진수로 저장
  • 자바스크립트는 2진수,8진수,16진수를 표현하기 위한 데이터 타입 제공 X → 값을 참조하면 모두 10진수로 해석

위에서 숫자타입은 모두 실수로 처리된다고 했다

console.log(1 === 1.0); // true
console.log(3/2); //1.5 

숫자타입에는 3 가지 특별한 값이 표현될 수 있다.

  • Infinity : 양의 무한대
  • -Infinity : 음의 무한대
  • NaN : 산술 연산 불가 ( not a number )
console.log(10/0); // Infinity
console.log(10/-0); // -Infinity
console.log(1*'String'); // NaN
  • 자바스크립트 소소한 정보
    • 자바스크립트는 대소문자를 구별한다. 따라서 NaN을 Nan,NAN, nan 같이 표현하면 에러 발생 → 자바스크립트 엔진은 식별자로 판단

string

  • 텍스트 데이터를 나타내는데 사용
  • 0개 이상의 16비트 유니코드 문자의 집합으로 전 세계 대부분의 문자 표현 가능
  • 문자열은 ‘작은따옴표’ , “큰따옴표” , 백틱으로 텍스트를 감싼다.
  • 자바스크립트에서 가장 일반적인 표기법은 ‘작은따옴표’ 사용
const string = `백틱`; // es6 부터 사용 가능 ->  es5에서는 그럼 안되는건가?

문자열은 왜 다른 타입과 달리 따옴표로 감싸는가?

  • 키워드나 실벽자 같은 토큰과 구분하기 위해서이다.
  • 만약 문자열 따옴표로 감싸지 않으면 자바스크립트 엔진은 키워드나 식별자 같은 토큰으로 인식
const string = hello; // 이렇게 식별자로 인식한다

템플릿 리터럴

  • es6부터 템플릴 리터럴이라고 하는 새로운 문자열 표기법 도입
  • 멀티라인 문자열, 표현식 삽입, 태그드 템플릿 등 편리한 문자열 처리 가능
  • 템플릿 리터럴은 런타임에 일반 문자열로 변환되어 처리된다.
  • 백틱을 사용해 표현해야한다
const template = `Template literal`;
console.log(template); // Template literal

여러줄이 있는 문자열을 표현할 때는 템플릿 리터럴을 사용하면 편할것이다 → 일반 문자열은 이스케이프 시퀀스를 활용해야하기 때문에 귀찮을 수 있다.

// 일반 문자열
const template1 = '<div>\n\t<span>아이고 귀찮아..</span>\n</div>'

//템플릿 리터럴
const template2 = `<div>
	<span>편하다 편해</span>
</div>`

//출력 결과 동일

표현식 삽입

const first = 'JongHun';
const last = 'Jun';
//es5
console.log('my name is ' + first + ' ' + last); // 너무 귀찮자나.. 공백 신경까지 해야해

//es6
console.log(`my name is ${first} ${last}`); // 편하고 가독성 업업

boolean

  • 논리적 참, 거짓을 나내태는 true / false
  • 프로그램 흐름을 제어하는 조건문에서 자주 사용됨

undefined

  • undfined 타입은 undefined가 유일
  • var 키워드로 선언한 변수는 암묵적으로 undefinde로 초기화 → 변수 선언에 의해 확보된 메모리 공간을 쓰리기 값이 있게 냅두지 않고 undefined로 초기화 한다는 얘기 → 변수 선언후 값을 할당하지 않으면? undefind
  • 변수를 참조했는데 undefined가 반횐되면? 선언 이후 값이 할당되지 않았다라고 판단할 수 있는 것 / 초기화 되지 않은 변수다
  • 자바스크립트 엔진이 변수를 초기화 할 때, undefined를 사용하므로 개발자는 undefined를 의도적으로 변수에 할당하는 것은 피하는게 좋다 → 취지와 어긋날뿐더러 혼란을 줄 수 있기 때문

변수에 값이 없다는 것을 명시하고 싶을때는?

  • null을 할당하면 된다

null

  • null 타입의 값은 null이 유일
  • 자바스크립트 대소문자 구별한다 했었다 → NULL, Null 등 X
  • 변수에 값이 없다는 것을 의도적으로 명시할 때 사용
  • null값을 할당하는 것은 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미
  • 자바스크립트 엔진은 참조하지 않은 메모리 공간에 대해 가비지 콜렉션을 수행
  • 함수가 유요한 값을 반환 할 수 없는 경우 명시적으로 null을 반환하기도 한다.

더 이상 사용하지 않을 것 같으면 null 할당 후 가비지 콜렉션 수행하게 하기?

let foo = 'jun'
//
//
// 여기 동안은 foo가 메모리에 있을거다!
//
//

//더 이상 필요없다고 생각해서 null을 대입해주면?
foo = null; // 자바스크립트 엔진이 가비지 콜렉션을 수행하면서 메모리의 공간을 확보!
  • 메모리 공간까지 생각해서 코딩을 한다면.. 이렇게 하는 방식도 좋아보인다고 생각한다. 하지만 현대 컴퓨터에서 메모리 공간을 이런 자잘한 것 까지 신경쓰지 않아도 될 것 같긴하다. → 메모리 공간이 중요하다고 생각하면 고려해보자

함수가 유요한 값을 반환 할 수 없는 경우

// html에 없다는 가정
const element = document.querySelector('.myClass');
console.log(element); // null 반환 -> 못 찾았다 해서 에러가 항상 나는 것은 아니다.

symbol

  • es6에 추가된 7번째 타입이다.
  • 원시타입이다.
  • 심벌 값은 다른값과 중복되지 않는 유일무일한 값
  • 이름 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용한다.
  • 심벌 이외의 원시 값은 리터럴을 통해 생성하지만 심벌은 Symbol 함수를 호출해 생성 → 생성된 심벌값은 외부에 노출되지 않으며, 다른 값과 절대 중복 X
let key = Symbol('key');
console.log(type of key); // symbol

//객체 생성
let obj = {};

// 이름이 충돌할 위험이 없는 유일무일한 값인 심벌을 프로퍼티 키로 사용한다.
obj[key] = 'value';
console.log(obj[key]); // value

심벌에 대한 자세한 내용은 여기로 ← 링크 걸어둘 예정


참조타입 / 객체타입

객체

  • 객체에 대해서는 아직 공부를 제대로 하지 않았기 때문에 객체 단원을 공부하고 채워나가볼 생각
  • 중요한 점은 자바스크립트는 객체 기반 언어이다!
  • 자바스크립트를 이루고 있는 거의 모든 것이 객체이다
  • 원시타입을 제외한 나머지는 참조타입이다!

그러면 왜 타입이 존재를 하는가? 왜 필요한가?

  • 값을 저장하려면 메모리공간이 필요하다
  • 메모리에 값을 저장하려면 얼만큼 공간을 확보해야할지 크기를 알아야한다
  • 즉, 몇 바이트의 메모리 공간을 사용해야 낭비와 손실 없이 값을 저장할 수 있는지 알아야한다
  • 값을 참조할 때 한번에 읽어 들어야 할 메모리 공간의 크기를 결정하기 위해서 알아야한다.
  • 메모리에서 읽어 들인 2진수를 어떻게 해석할지 결정하기 위해서 알아야한다.
const score = 100; // 숫자 100을 저장하면 어떻게 될까?
  1. 위 코드가 실행되면 숫자 100을 저장하기 위해 메모리 공간을 확보한다.
  2. 자바스크립트 엔진은 변수에 할당된 값의 타입에 따라 메모리 공간을 확보한다. ex) number type ⇒ 8Byte
  3. 메모리 공간에 100을 2진수 형태로 저장한다.

다른 데이터 타입들의 크기는 어떨까?

  • 문자열, 숫자 타입 외의 데이터 타입의 크기를 명시적으로 규정하고 있지 않는다고 한다.
  • 문자열, 숫자 타입 제외하고는 데이터 타입에 따라 확보되는 메모리 공간의 크기는 자바스크립트 엔진 제조자의 구현에 따라 다를 수 있다.
  • 자바스크립트는 숫자형 데이터에 대해 64비트(8바이트)의 공간을 확보한다고 했다. 반면 문자열은 특별히 정해진 규격이 없다. 한 글자마다 영어는 1바이트, 한글은 2바이트 등으로 각각 필요한 메모리 용량이 가변적이며 전체 글자 수 역시 가변적이기 때문이다.

자바스크립트는 동적 타입 언어? 정적 타입 언어?

  • 자바스크립트는 동적 타입 언어이다
  • 정적 타입 언어는 변수를 선언할 때 변수에 할당할 수 있는 값의 타입을 같이 선언해줘야한다 ⇒ 명시적 타입 선언
// C언어 예시
int number = 10; // 4바이트 정수 타입 넣을 수 있어요~
  • 정적 타입 언어에 대한 내용 궁금하면 눌러보자
    • 정적 타입 언어는 변수의 타입 변경 X, 타입에 맞는 값만 할당 가능
    • 컴파일 시점에 타입 체크함 ⇒ 선언한 데이터 타입에 맞는 값을 할당했는지 검사하는 과정 → 통과 못하면 에러 발생
    • 이를 통해 타입의 일관성을 강제함으로써 안정적인 코드 구현을 통해 런타임 에러 줄인다

자바스크립트는 그러면 어떻게 되는거야..?

  • 변수 선언시 타입 선언을 하지 않는다. var, let, const 키워드를 사용할 뿐!
  • 어떠한 데이터 타입의 값이라도 자유롭게 할당 가능! ⇒ 동적 언어란 말씀

타입을 확인해보자

const name = '전종훈';
console.log(typeof name); // string
  • typeof 연산자를 사용하면 데이터 타입을 반환한다 ⇒ 엄밀히 말하자면 변수의 데이터 타입이 아닌 변수에 할당된 값의 데이터 타입을 반환!

그렇다면 정적 타입 언어와 동적 타입 언어의 구별은 어떻게 해야할까?

  • 정적 타입
    • 선언할 때, 타입이 결정!
  • 동적 타입
    • 할당할 때, 타입이 결정! ⇒ 타입 추론(type inference)
    • 재할당의 의해 변수의 타입은 언제든지 동적으로 변할 수 있다 ⇒ 동적 타이핑(dynamic typring)

그래서 변수는 타입을 가진다 안가진다?

  • 변수는 타입을 기본적으로 안 가진다
  • 값은 타입을 가진다
  • 현재 변수에 할당되어 있는 값에 의해 변수의 타입이 동적으로 결정된다라고 표현이 적절하다!

그러면 이런 생각을 할 수도 있을 것 같다. 동적 타입 언어 유연하고 좋은데? 이러한 것이 장점이 될 수도 있지만 오히려 독이 될 수도 있다.

  • 변수의 값이 언제든지 변경 될 수 있다는 건 복잡한 프로그램에서는 변수의 값을 추적하기 어렵다는 얘기
  • 동적 타입 언어의 변수는 값을 확인하기 전까지 어떤 타입인지 알 수 없다..
  • 또는 자바스크립트는 개발자의 의도와 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다 ⇒ 즉, 숫자타입 변수일 것이라고 예측 했지만 사실은 문자열 타입 변수일 수도 있다는 것.. → 자연스럽게 오류 확률 업..오마이갓
  • 그렇다고 매번 변수를 사용하기 전에 타입 체크를 하는 것은 코드 양도 많아지고 번거롭다.. 가독성 떨어진다

정리하자면! 동적 타입 언어는 자유성 굿이야👍 하지만! 신뢰성 꽝..

자바스크립트에서 변수를 사용할 때 주의할 사항

  • javaScript Deep Dive 73 쪽 참고하여 정리해두기
profile
기타치는 프론트 개발자

0개의 댓글