JS- 변수와 타입

hoin_lee·2023년 9월 29일
0

TIL

목록 보기
219/234

그동안 수업 들으면서 정리했던 부분들을 매일 작성했어야 했는데 이해하는 데 시간이 좀 걸리고 잠깐 블로그를 놓았던 것 같다

변수와 상수

기본적으로 변수는
선언 + 식별 + 타입 + 값 + 스코프 로 이루어져 있다
선언은 var,let,const 등이 있고 식별자는 변수의 이름이라 생각하면 좋고 타입또한 js에선 실행 당시 알게 되지만 그렇다고 없어야 하는 건 아니다.
타입 스크립트를 배울 때나 다른 언어에서는 외부적으로 작성해줘야 하니 기억해놓자
그리고 값과 스코프가 있다

ex) var name = "lee" , let age = 15, const birtday = 0101

식별자

식별자는 말 그대로 변수를 식별하기 위해 필요한 것으로 우리가 코드를 작성할 때 변수 선언을 하게 될 경우 선언문 뒤에오는 것이 보통 식별자이다
var name = "lee"에서 name이 식별자 역할을 한다
이때 식별자의 규칙이 하나 있는데

  • 문자 , $, _ 로 시작 (숫자는 식별자의 첫 글자론 사용하지 못한다)
  • 파이 문자 같은 유니코드
    가 있다.
    식별자 같은 경우는 회사마다 어떻게 사용할지 다르니 각 코드 컨벤션을 지켜서 작성하면 될 것 같다.
    또한 식별자를 막 a,b 이런식으로 적을 경우 혼란을 야기하니 주의하자.
    항상 기억해야한다. 컴퓨터가 이해할 수 있는 코드로 바꿔주는 것은 컴파일이지 우리가 작성한 코드를 보는 것은 사람이다.
    코드가 즉 주석이라고 생각하며 작성하자

타입

JS에선 타입이 2가지가 있는데

  • Object Type
  • Reference Type
    이 있다. 참고로 JSON과 Object가 동일하다고 생각하면 안된다. JSON은 Notation일 뿐이다.
    즉 표기법을 말할 뿐

Primitive 타입

타입을 중요시 생각하는 이유는 값이 어떤 메모리에 들어가는지를 생각한다면 이해하기 쉽다
Primitive / Value Types 들은 immutable 하다.
여기서 immutabel이란 불변성으로 변하지 않는 것이다
일단 이 타입들은 값이 보통 stack에 존재하게 되는데
쉽게 표현하자면
STACK이란 메모리에 &10 번지 메모리 주소에 식별자 a로 값이 1 저장된것이다
우리가 코드를 조금 배웠다면 만약 이 avar나 let로 선언됐다면 다시 변경할 수 있다고 생각할 수 있다.
그럼 여기서 의문점이 생긴다. 값을 변경하는데 "그럼 &10번지에 있던 a의 값이 변경되는 것이기 때문에 immutable한 건 아니지 않나요?" 라고 생각할 수 있다

하지만 메모리 저장 과정을 본다면 immutable 한거구나 이해할 수 있다

새롭게 값을 할당했을 때 &10번지에 있는 a값이 변경되는 것이 아니라 실제론 &10번지에 있던 a가 아닌 새로운 &11번지에 a를 새로운 값으로 저장한다.
그리고 원래 &10번지에 a는 아무도 참조하고 있지 않는 상태가 되어 G.C가 돌게되어 삭제된다.

그렇기에 &10번지의 값을 변경한 것이 아니기 때문에 불변하다는 법칙이 적용되는 것이다

종류로는

  • 숫자(number)
  • 문자열 / 문자열 템플릿
  • boolean
  • null
  • undefined
  • symbol
    등이 있다

Refrence 타입

Refernce 타입은 말 그대로 참조 타입으로 메모리에 저장될 때 값이 저장된다기 보단 메모리 주소가 저장된다 생각하면 이해하기 편하다

저장되는 값들을 생각하면 Object타입일 텐데 이 Object들은 값이 가변성을 띈다
가변성을 띄는 값들은 stack에 저장할 경우 낭비가 심하니 Heap이란 메모리 영역에 저장하는데 이 Heap영역은 매우 넓은 저장공간이다
이곳에 저장된 이 Object의 위치들을 stack에서 메모리 주소로 저장시키는 것이다.
그렇기에 이 메모리 주소를 참조 하고 있다고 해서 참조 즉 Refrence 타입이다.

그럼 우리가 const를 사용하면서 생기는 의문점이 확실하게 이해된다
왜 const 로 Refrence타입을 저장했는데 object나 array안은 변경 되는거지? 이부분이 확실하게 이해된다

const obj = {id:1, name:"lee"}
obj. name = "hong"
console.log(obj) // {id:1 , name:"hong"}

왜 이렇게 되는것일까? 위에 설명한 걸 그대로따라 한다면 위의 obj는 실제 STACK 메모리 주소에 obj란 식별자에 {id:1,name:"lee'}가 저장된 것이 아니라 HEAP에 저장된{id:1,name:"lee'}값의 주소를 가지고 있는 것으로 해당 값이 HEAP의 &100번지에 존재한다면 실제 STACK에는 obj란 식별자에 &100번지라는 메모리 주소가 저장되어 있는 것이다.

그렇기에 HEAP에 있는 객체의 name을 변경한다고 해도 &100번지라는 메모리 주소는 동일하니 실제로 obj의 값은 변하지않은것이다.

따라서 이런것도 생각해 볼수가 있다

const obj1 = {id:1, name:"lee"};
const obj2 = obj1

obj2.id = 3
console.log(obj1) //{id:3, name:"lee"}
console.log(obj2) // {id:3, name:"lee"}

만약 메모리 주소를 이해 못했으면 바로 "????"이 뜰 것 같은 코드다.
근데 위의 Refrence타입의 저장 과정을 이해했다면 이해하기 편하다.
Primitive에서 위와 같이 쓴다면??

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

다르게 동작하는 것을 확인할 수 있는데 이유는 이렇게 let a = b라고 사용할 경우 b가 가진 값을 그대로 가져가는 것을 볼 수 있는데 Primitive 타입은 해당 값을 그대로 저장하고 있기 때문에 그대로 값 1만 전달해주는 것으로 끝나지만

Refrence 타입은 메모리 주소를 그대로 가져가는 것이기 때문에 해당 메모리 주소의 값이 변경된다면 다른 변수에도 영향을 끼치는 것이다

obj1의 값인 &100번지 메모리 주소를 복사해서 obj2에 할당했으니 obj2도 &100번지 메모리 주소를 값으로 가지고 있을테고 obj1을 통하든 obj2를 통하든 &100번지의 값을 변경할 경우 두가지 다 결국에 &100번지를 보고 있으니 값이 바뀌는 것이다.

string타입에 대한 STACK과 HEAP저장은 이전에 constant pool에 한번 다룬 적이 있으니 한번 보면 좋을 것 같다
https://velog.io/@lee_moi/javascript-%EC%97%90%EC%84%9C%EC%9D%98-constant-pool


기본적인 타입과 타입이 저장되는 메모리의 설명은 끝났는데 JS를 배우면서 항상 주의해야 하는 것이 있따.
JS는 객체 기반의 언어이며 원시값(primitive)를 제외한 모든 것이 객체다.
(참고로 string 또한 JS에선 primitve값으로 보고 있지만 다른 언어에선 객체로 인정한다. char Array 로 분명히 단어 하나하나가 쭉 array로 나열된 것이기 때문에 [index]로 접근 할 수 있는것이다)

JS는 런타임에 타입이 정해지는 동적(Duck) 타이핑!(할당 시 추론 infernce)

profile
https://mo-i-programmers.tistory.com/

0개의 댓글