[JS] Primitive type & Object type

JunSeok·2023년 10월 24일
0

Javascript

목록 보기
1/16
post-thumbnail

목표

Primitive type 값과 Object type 값이 자바스크립트 엔진에 저장되는 방식을 알 수 있다.

Primitive type

ES2020 기준으로 총 7개가 있다.

  • Number
    - 64비트 부동 소수점 방식으로 표현
    - 64비트 중에서 53비트만 수를 저장하고 나머지는 소수점 자리와 기호를 저장한다.
    - 때문에 2^53-1까지 정확성 보장,이 값을 넘으면 BigInt 사용
    - Number.MAX_SAFE_INTEGER에 2^53-1 값이 상수로 저장되어있다.
  • String
    - 한 문자당 16비트가 고정적으로 할당된다.
    - 문자열은 배열이 아닌 유사배열이다.
    • 유사배열은 key가 index이고, length 값을 가지고 있는 객체이다.
    • 유사배열에는 NodeList, HTMLCollection 등이 있다.
    • 배열이 아니기 때문에 배열 메서드를 사용할 수 없다.
    • 대신 iterable한 것을 배열로 바꾸는 Array.from()을 사용하면 가능하다.
  • Boolean
    - 1비트의 크기 할당
    - true, false로 나눈다.
    - logical operator 또는 제어문의 조건식과 같은 context에서는 false가 아니지만 false로 판단되는 falsy value가 있다. 아래 값을 제외한 모든 값은 truthy value이다.
    • false
    • 0, -0
    • ''
    • undefined
    • null
    • NaN
  • undefined
    - 선언 이후 값이 할당되지 않은 변수를 undefined로 초기화한다.
    - 때문에 개발자가 의도적으로 undefined를 사용하는 것은 권장하지 않으며 만약 변수의 값이 없다는 것을 명시하고 싶으면 null을 사용하면 된다.
  • Null
    - 의도적으로 값이 없음을 명시하기 위한 데이터 타입이다.
    - null의 할당은 변수에 연결된 메모리 주소 참조를 제거하겠다는 의미이다.
    - 이후 자바스크립트 엔진은 참조하지 않은 메모리 영역(null 할당을 통해 메모리 주소 참조가 제거된 변수)에 대해 가비지 컬렉션을 수행하게 된다.
  • Symbol
    - ES6에 새롭게 추가
    - 이름 충돌 위험이 없는 고유한 값으로 만들기 위해 사용
    - 객체의 프로퍼티 값으로 활용 가능
  • BigInt
    - Number의 정확성을 보장해주는 최댓값인 2^53-1보다 큰 수 저장, 연산 가능
    - 정수 끝에 n을 추가하거나 생성자를 호출하는 방식으로 가능
    - BigInt 타입의 수는 BigInt 타입의 수하고만 연산이 가능하다.(논리연산과 문자열 연결은 예외)
	// 뒤에 n을 붙이는 방법이 제일 낫다.
	const BiggestInt1 = 99999999999999999999n;
	
	// 엄청 큰 숫자를 자바스크립트 내부적으로 나타낸 뒤에 BigInt 함수에 씌우는 것이라서 값이 조금 달라질 수 있다.
	// 그래서 BigInt는 작은 수를 BigInt 타입의 수와 연산하기 위해 BigInt 타입으로 바꿀 때 사용하면 된다.
	const BiggestInt2 = BigInt(9999999999999999999999)

Object type

자바스크립트에서 Primitive type을 제외한 모든 값을 Object type이라 할 수 있다.

  • Object
  • Array
  • Funtion
  • ETC...

자바스크립트 엔진

자바스크립트 엔진은 함수를 실행하는 call stack과 heap 메모리로 구성된다.

  • Primitive type의 값은 함수를 실행하는 Call stack에 저장된다.
  • Object type의 값은 Heap 메모리에 저장된다.

value 저장 방식

Primitive type 저장 방식

Primitive type의 값은 Call stack에 저장된다.

  • 자바스크립트는 변수의 이름으로 고유의 식별자(unique identifier)를 생성한다.
  • Primitive type 값의 크기는 고정되어 있기 때문에 그 크기만큼 할당된 Call stack 메모리에 실제 값을 저장한다.
  • 생성된 식별자는 값 자체가 아니라 값이 저장된 stack 메모리 주소를 가리킨다.
  • 변수에 새로운 값을 할당하게 되면 가리키고 있는 메모리 주소의 값이 변하는 것이 아니라 새로운 값이 할당된 메모리 주소를 가리킨다.
    -새로운 값을 할당할 때 메모리 주소의 값이 변하게 되면 이전에 이 메모리 주소를 가리키는 변수의 값도 바뀌기 때문에 데이터의 신뢰성을 보장할 수 없다.
    -데이터의 신뢰성을 보장하기 위해 Primitive type의 값은 immutable한 성질을 갖는다.
    -이를 위해 값이 변하는 대신 새로운 값을 가진 메모리가 할당된다.

Object type 저장 방식

모든 Object type의 값은 heap 메모리에 저장된다.

  • Object type의 값은 가변적이며 크기가 매우 커질 수 있기 때문에 stack이 아닌 heap에 저장한다.

  • Object type의 값이 새로 생성되면, 그 값은 새로 할당된 heap 메모리에 저장된다.

  • Primitive type과 동일하게 stack에서는 값을 할당받는 변수의 이름으로 식별자가 생성된다.

  • 이 식별자는 stack에 새로 할당된 메모리 주소를 가리키는데, 이 메모리 주소의 값은 실제 Object type 값이 아니라 Object type 값이 저장된 heap 메모리의 주소이다.

  • 다시 말해 stack에 있는 식별자가 가리키는 stack에 할당된 메모리 주소의 값은 heap에 저장된 Object type의 값이라는 것이다.

  • stack에서는 Object type의 값이 저장된 메모리 주소를 알고 있기 때문에 필요할 때마다 사용할 수 있다.

  • 주의해야 할 점은 값을 완전히 바꾸는 것과 단순히 property를 바꾸는 것은 다르다는 점이다.
    -const 변수로 선언해도 값을 바꿀 수 있다. const 변수가 가리키는 stack의 메모리 주소값이 변한 것이 아니기 때문이다. 즉 Object type은 mutable한 성질을 갖는다.
    - 즉 stack의 값은 변함없어야 한다. 같은 메모리 주소를 가리켜야 한다. (let으로 선언할 경우 다른 메모리 주소 할당 가능)
    - 새로 할당된 값을 const로 선언된 변수에 할당하게 되면, 새로운 메모리 주소를 stack의 메모리에 넣는 것이기 때문에 불가능하다.
    -바꿀 수 있는 것은 기존의 stack메모리 주소가 가리키고 있는 heap에 저장된 값이며, 바꿀 수 없는 것은 stack의 메모리 주소이다.
    -두 변수가 같은 값을 할당받을 경우, stack에서 동일한 heap 메모리 주소를 가리키기 때문에 값을 변경할 경우 같은 값을 가진 변수의 값이 모두 변한다.
    -즉 같은 것을 다른 이름으로 부르는 것과 같다.

    const a = { name: 'aaa' }
    // 같은 값을 가리킴
    const b = a
    a.name = 'bbb' // 가능
    b.name = 'ccc' // 가능, a의 값도 같이 바뀜
    a = {} // 불가능
    
    // let으로 선언하면 가능
    let a = { name: 'aaa' }
    a.name = 'bbb' // 가능
    a = {} // 가능
    	```

pass by value & pass by reference

자바스크립트는 모두 pass by value이다.
실제 값이든, 메모리 주소든 stack에서는 모두 값으로 취급하기 때문에 참조에 의한 전달은 존재하지 않고 값에 의한 전달만 존재한다.
즉 메모리 주소를 참조하는 것이 아니라 메모리 주소를 다른 변수에 전달하는 것 그뿐이다.

참조

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures
https://www.udemy.com/course/the-complete-javascript-course/
https://poiemaweb.com/js-data-type-variable
https://poiemaweb.com/js-type-coercion
https://poiemaweb.com/js-function

profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글