Core Javascript - 데이터 타입

kyj2471·2021년 3월 29일
0

Core

목록 보기
1/2
post-thumbnail

코어 자바스크립트란 책을 읽으면서 스스로 정리한 내용입니다
혹시 잘못된 내용이 있으면 수정하겠습니다.

데이터 타입

👍 배우는 이유? 자바스크립트가 데이터 처리 과정을 보고 기본형과 참조형이 왜 다르게 동작하는지를 이해하여 활용하기 위해 배운다.

데이터 타입의 종류
우리가 javascript를 사용하면서 자주 사용하는 데이터 타입은 크게 두가지로 나뉜다

기본형 타입(primitive type)

  • Number
  • String
  • Boolean
  • Null
  • Undefined
  • Symbol

참조형 타입(reference type)

  • Object
  • Array
  • Function
  • Date
  • RegExp(정규식 표현)
  • Map,WeakMap
  • Set,WeakSet

Symbol

여기서 다른건 많이 사용해 익숙하지만 Symbol은 아직까지 많이 사용해 보지 못하였다.

심볼은 ES6에 새로 추가된 타입이다.
Symbol에 대해 공식문서를 참고해 보면 심볼은 객체 프로퍼티에 대한 식별자로 사용되며 이것이 심볼데이터 형식의 유일한 목적이라고 한다.

결론적으로 Symbol은 유일한 식별자를 만들고 싶을 때 사용한다.
아래 코드를 보면서 이해해보자

const a = Symbol(); //new를 붙이지 않는다.
const b = Symbol();
const id = Symbol("id");//id-->description
const id2 = Symbol("id");

console.log(a)  //Symbol()
console.log(b)  //Symbol()
console.log(a===b)//false
console.log(a==b)//false

console.log(id)//Symbol(id)
console.log(id2)//Symbol(id)
console.log(id === id2)//false
console.log(id == id2)//false

이제 이 Symbol을 객체의 키로 사용해보자.

const id = Symbol("id");
const user={
  name : "yeongjae",
  age : "29",
  [id] : "smile"
}

console.log(user)//{ name: 'yeongjae', age: '29', [Symbol(id)]: 'smile' }
console.log(Object.keys(user))// ["name","age"]
console.log(Object.values(user))// ["yeongjae","29"]

for(let key in user){
  console.log(key) //"name" "age"
}

근데 이렇게 숨겨진 녀석을 어떻게 쓰는걸까?

const user={
  name : "yeongjae",
  age : "29"
}
const id = Symbol();
user[id] = "HI";

위의 코드에서 알 수 있듯 user[id]라는 computed property name을 사용해 추가했을때 특정 객체에 원본 데이터를 건드리지 않고 속성을 추가 할 수 있다.

마지막으로 우린 Symbol을 알게 모르게 사용하고 있었다.
바로 Spread연산자로 Spread연산자는 Symbol.iterator이란 메서드를 사용해서 사용하는 것이였다.

이터레이터는 순회 가능한 자료구조인 이터러블 요소를 탐색하기 위한 것으로 value,done프러퍼티 객체를 반환하는 next()함수를 메소드로 갖는 객체이다. 이터레이터는 이 메소드를 통해 이터러블 객체를 순회할 수 있게 되는 것이였다.

식별자? 변수?

다시 데이터 타입으로 돌아와 보자.
우선 데이터 타입을 보기전 식별자와 변수에 대해 알아보자.
변수란 변할 수 있는 무언가 라고 이해 하면 된다.
여기서 무언가는 데이터를 의미한다.
숫자,문자역,객체,배열 모두 데이터이다.

식별자는 어떤 데이터를 식별하는데 사용하는 이름이다. 즉, 변수명이다.

var a;

우리가 항상 쓰던 코드이다.
이걸 말로 표현해보면 변할 수 있는 데이터를 만든다. 이 데이터의 식별자는 a 입니다.
라고 표현 한다.

기본형 vs 참조형

간단히 말하면 기본형과 참조형의 차이는 복제하는 것으로 나뉜다.
따지면 기본형, 참조형 모두 복제를 하지만 기본형은 값이 있는 주소를 바로 복제하지만 참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제하는 점이 다르다.

불변값?

기본형 데이터는 불변성을 가집니다. 그런데 불변성이 무슨 말일까?

let a = 5
let b = 5
a = 7
console.log(a) // 7

처음 공부하면서 바로 생각난게 위의 코드였다.
뭐야? 기본형 데이터 변하는데 왜 불변성이야?

위의 코드에서 변수 a에 숫자 5를 할당한다. 그러면 컴퓨터는 데이터 영역에서 5를 찾는다. 없다면 데이터 공간 하나에 5를 저장한다 그리고 난 뒤 b라는 변수가 선언되고 컴퓨터는 이미 데이터 영역에 저장된 5라는 데이터를 재활용한다.
그리고 나서 a = 7이라고 바꾸려고한다. 이때 5라는 데이터를 지우고 7을 사용하는게 아니라 5라는 데이터는 상관없이 다시 컴퓨터는 7이란 데이터를 찾고 만약 없다면 새로운 데이터 영역에 7을 선언하게된다.

이처럼 한번 선언한 값을 바꿀수 없습니다.
변경은 새로 만드는 동작을 통해서만 이뤄지는데 이는 불변값의 성질입니다.
즉, 한번 만들어진 값은 가비지 컬렉팅을 당하지 않으면 영원히 변하지 않습니다.

가비지 컬렉팅 대상? 참조 카운트가 0인 메모리들. 수거된 메모리는 다시 새로운 값을 할당 할 수 있는 빈 공간이 된다.

가변값?

위에서 보았듯 기본형 데이터는 불변성은 띈다.
그렇다면 참조형 데이터는 가변성을 띄는 것일까?
결론 부터 말씀 드리면 참조형 데이터가 가변값이라 말하는건 데이터 자체를 변경할 때가 아닌 그내부의 프로퍼티가 변경될 때만 성립된다.

바로 코드를 보도록 하자.

let a = 10;
let b = a;
let obj1 = {c:10, d:"yeongjae"}
let obj2 = obj1

b = 15;
obj2.c = 20;
console.log(a === b)//false
console.log(obj1 === obj2)//true

이제 콘솔값이 저렇게 나오게된 이유를 알아보자.

우선 기본형 데이터인 식별자 a와 b는 10이란 데이터를 가지고있는 주소를 같이 쳐다보고있다.
obj1,obj2또한 같은주소를 바라 보고있을것이다.
여기서 obj1, obj2가 바라보는 주소는 c,d이름을 가지고있는 데이터 주소를 쳐다보고있다. 그 주소는 다시 10과 "yeongjae"라는 데이터를 가진 곳을 쳐다보고있다.

여기서 b=15 obj2.c=20로 선언했을 때 b는 15라는 데이터를 가진 주소를 쳐다보게 될것이다.
하지만 obj2는 똑같은 주소를 쳐다보고있다.
그주소는 c이름을 가진 데이터주소를 그대로 보고있지만 c데이터를 가진 주소가 20이란 데이터를 가진 주소를 보게된다.

이렇게되면 a,b는 결과적으로 다른 주소를 보고 obj1,obj2는 같은 주소를 보는 것이다.
이러한 현상의 결과가 아래 코드인 것이다.

console.log(a === b)//false
console.log(obj1 === obj2)//true

위에서 "참조형 데이터가 가변값이라 말하는건 데이터 자체를 변경할 때가 아닌 그내부의 프로퍼티가 변경될 때만 성립된다"
라고 했는데 이 이유는 위의 상황과 다르게 만약 아래의 코드 처럼 한다면

obj2 = {c:20, d:"HappyCoding"}
console.log(obj1 === obj2)//false

서로 다른 주소값을 참조하고 결과는 서로 다른 주소를 보고있음으로 false가 된다.

profile
[ frontend-developer ]

0개의 댓글