[JS] 원시 자료형과 참조 자료형 비교

김재훈·2022년 11월 6일
2

오늘은 원시 자료형과 참조 자료형을 비교 학습해보겠습니다. ☺️

⚠️Disclaimer⚠️
🙏 아래 자료는 개인 공부를 위해 정리한 자료로 보다 정확하고 자세한 정보는 글 하단에 Reference 를 통해 확인하실 수 있습니다.
🙏 Stack->Heap이 연결되는 도식은 이해를 돕기 위해 실제 형태와는 다소 차이가 있을 수 있습니다.

Objectives

  1. 원시 자료형의 종류와 특징 이해하기
  2. 참조 자료형의 종류와 특징 이해하기
  3. 둘의 차이를 이해하고, 코드 작성에 응용하기

원시 자료형

원시 자료형(Primitive Type)은 method/property를 가지지 않는 객체가 아닌 자료를 담기 위한 자료형(ref.1)입니다.
그 종류는 7가지로 각각 다음과 같습니다.

  • String
    문자열을 담기 위한 자료형입니다.
  • Number
    배정밀도 부동소수점 수를 담을 수 있는 자료형입니다. 우리가 흔히 사용하는 일반적인 수를 대부분 담을 수 있습니다.
  • BigInt
    정수나 실수에 대하여 제한이 없는 큰 수를 담기 위한 자료형입니다.
  • Boolean
    참/거짓으로 분류되는 논리값을 담기 위한 자료형입니다.
  • undefined
    값을 할당하지 않았을 때 자동으로 선언 시 할당되는 자료형입니다.
  • null
    비어있다는 것을 명시적으로 나타내는 자료형이며, 유효하지 않은 객체나 주소값을 참조했다는 의미를 담을 때 많이 사용됩니다.
  • symbol
    Symbol(ref.2) 값을 담기 위한 자료형입니다.

참조 자료형

참조 자료형(Objects)은 메모리 내에 저장된 값에 접근할 수 있는 식별자를 담을 때 사용하는 자료형(ref.3)입니다. 한 식별자로 여러 값을 담을 때 값은 늘어나거나 줄어들 수 있습니다.

배열 arr에 저장된 값을 연속적으로 저장하기 위해 arr 이후에 등장하는 변수들을 임시 영역으로 옮긴 후 arr에 추가된 값을 다시 저장하고, 임시 영역에 옮겨둔 변수들을 다시 그 뒤에 저장하는 것은 매우 비효율적입니다. 이러한 비효율은 참조 형태의 자료가 많을 때 더 극대화됩니다.

그렇기에 배열/객체/함수가 갖고 있는 데이터는 힙 영역에 저장하고 일반적인 자료가 저장되는 스택 영역에는 힙 영역에 저장된 데이터를 호출하기 위한 주소가 저장됩니다.(ref.4)

주소 형태로 저장하면 기존 저장된 스택 영역에 영향을 끼치지 않고도 자유롭게 값을 참조하고, 추가/삭제할 수 있습니다.

힙 영역에 어떻게 저장되고, 스택 영역에는 어떻게 저장되는 지에 대한 코드 부분도 궁금했으나 JavaScript 런타임의 코드를 해석할 수 있어야 이해가 가능한 부분이라 나중에 다시 알아보기로 했습니다. 해당 코드는 v8 GitHub(ref.5)에서 확인 가능합니다.

비교

각 자료형의 비교에 대한 스택오버플로우 글(ref.4)에 따라 정리하자면 아래와 같이 분류 가능합니다.
(괜찮은 한국어 번역을 찾지 못 해 단어는 원문 그대로를 사용했습니다.)

  • Primitive values: 원시 자료형의 값들로 이 유형에 속하는 데이터들은 Stack 영역에 값이 저장됩니다.
  • Primitive value: 원시 자료에 해당하는 데이터는 값이 저장된 영역에 바로 저장됩니다.
  • Reference values: Objects에 해당하는 자료들로 Heap 영역에 저장됩니다.
  • Reference value: 변수 위치에 저장된 값으로 객체(Object)가 가지고 있는 데이터의 위치를 참조하는 주소값을 의미합니다.

예제

원시 자료형의 값을 담은 변수끼리 비교하게 되면 어떤 일이 벌어지는지 실제 코드로 확인해봅시다.

const str1 = 'isPrimitive'
const str2 = 'isPrimitive'

console.log(str1 === str2) // -> true

실행 결과로 원시 자료형으로 저장된 값들은 실제 값이 동일하다면 비교 시 일치한다는 것을 알 수 있습니다.
반면 참조 자료형의 값들은 위와는 다른 결과를 보여줍니다.

// Array
const arr1 = [1,2,3]
const arr2 = [1,2,3]
console.log(arr1 === arr2)			// false
console.log(arr1[0] === arr2[0])	// true
console.log(arr1[1] === arr2[1])	// true
console.log(arr1[2] === arr2[2])	// true

// Object
const obj1 = {name: 'obj'}
const obj2 = {name: 'obj'}
console.log(obj1 === obj2)				// false
console.log(obj1.name === obj2.name)	// true

// Function
function fun1() {
    return 'returnedString'
}
function fun2() {
    return 'returnedString'
}
console.log(fun1 === fun2)		// false
console.log(fun1() === fun2())	// true

실행 결과로 참조 자료형은 직접 비교 시에는 일치하지 않지만 배열의 원소, 객체의 프로퍼티, 함수의 반환 값처럼 원시 자료형으로 나타낼 수 있는 것을 직접 비교하면 일치한다는 것을 알 수 있습니다.

Reference

footnote
1. https://developer.mozilla.org/en-US/docs/Glossary/Primitive#primitive_wrapper_objects_in_javascript
2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#objects
4. https://stackoverflow.com/a/13266769
5. https://github.com/v8/v8

etc

profile
개발하면서 새롭게 배운 내용, 시행착오한 내용들을 잊지 않기 위해 기록합니다.

0개의 댓글