[JavaScript - 심화] 원시타입과 객체타입

2024. 11. 5. 11:02·javascript

원시타입과 객체타입의 차이 (글)

원시 타입과 객체 타입의 차이점을 알아보자. 자바스크립트의 타입은 크게 원시 타입과 객체 타입으로 나눠지게 된다.

자바스크립트 모든타입을 원시타입과 객체타입으로 구분하는 이유는,

원시타입과 객체타입은 값이 저장되거나 복사되는 과정이 서로 다르기 때문이다.

원시 타입의 경우에는 값 자체로서 변수에 저장되고 복사되는 반면에, 객체 타입의 경우 참조값을 통해 변수에 저장되고 복사된다.

원시타입과 객체타입의 차이 (예시)

예시를 들어 이해해보자!

원시타입

첫 번째, 아래와 같은 코드가 있다고 해보자. p1에는 1이라는 값으로 초기화하고 p2에는 p1에 저장된 값을 복사했다.

let p1 = 1;
let p2 = p1;

메모리에는 아래처럼 저장된다.

만약에 p2의 값을 2로 변경시키는 코드를 추가하면 어떻게 될까?

let p1 = 1;
let p2 = p1;

p2 = 2;

메모리 공간에 2라는 값이 없으므로, 2를 새로운 공간에 저장하고 p2변수가 1이 아닌 2를 가리키도록 만든다.

이 때, 주의해야할 점! 변수의 값을 1에서 2로 변경하더라도, 메모리 공간에 저장된 원본 데이터 값은 실제로는 수정되지 않는다는 것이다. 원본 데이터가 수정되는게 아니라는 의미에서 원시 타입을 불변값이라고 부르기도 한다.

이 때 오해하지 말자! ❌ 변수의 값을 바꿀 수 없는 상수여서 불변값인게 아니다! ❌실제로 메모리 공간에 저장된 원본 데이터 값이 수정되지 않는다는 의미에서 불변값이라고 하는 것이다.

객체 타입

객체 타입의 값들은 어떻게 동작하는지 살펴보자.

let o1 = { name: '이정환' };

객체의 경우, 메모리에 아래처럼 저장되지 않을까 생각이 들겠지만 틀렸다!!

❌

대신에 메모리 어딘가에 객체를 저장해둔 뒤, 변수 o1에는 객체값이 저장된 메모리 공간을 가리키는 주소값인 참조값을 저장한다.

⭕

객체 타입의 값을 이러한 방식으로 저장하는 이유는 객체가 여러 개의 값을 담을 수 있는 구조를 가지기 때문이다. 원시 타입 값과 달리, 객체는 하나의 값만을 저장하지 않고, 동적으로 늘어나거나 줄어들 수 있는 여러 개의 값을 담을 수 있다. 이러한 유연한 특성 때문에 객체 타입의 값은 힙(heap)이라는 별도의 메모리 공간에 저장된다.

이제, o2라는 변수를 추가적으로 선언하고, o1의 값을 복사하도록 초기화를 시켜보자.

let o1 = { name: '이정환' };
let o2 = o1;

두 변수가 모두 같은 참조값을 가리키는 상태가 된다.

따라서 o2.name을 아래와 같이 수정하면,

let o1 = { name: '이정환' };
let o2 = o1;

o2.name = '홍길동';

o1과 o2가 동일한 객체를 참조하고 있으므로, 이 객체의 name 속성을 수정하면 두 참조 모두 그 변경 사항을 반영하게 된다. 처음에는 name 속성이 '이정환'이었지만 홍길동으로 수정했기때문에, o1.name을 출력해도 '홍길동'이 나온다.

이는 객체 타입의 값이 참조에 의해 관리되기 때문이다. 객체를 복사할 때 원본 데이터의 복사본이 아니라 원본 객체의 메모리 주소(참조값)만 복사된다. 따라서, 객체의 속성을 수정하면 메모리 상의 동일한 객체가 변경되므로, 그 객체를 참조하는 모든 변수(o1, o2 등)에서 동일한 수정 사항을 확인할 수 있다.

객체 타입을 다룰 때 주의해야할 점

① 의도치 않게 값이 수정될 수 있다.

 

앞에서 살펴본 객체 타입의 특성상, 객체를 다룰 때는 주의해야할 것이 몇 가지 있다.

따라서 이를 방지하기 위해서, 참조를 복사하는 것이 아닌 새로운 객체를 생성하도록 코드를 작성해야 한다.
새로운 객체를 생성하고, 속성을 복사해오는 식으로!

스프레드 연사자를 이용한 객체 생성

let o1 = { name: '이정환'};
let o2 = { ...o1 };

스프레드 연산자를 통해 복사하면, 메모리는 다음과 같이 된다.

let o1 = { name: '이정환'};
let o2 = { ...o1 };

o2.name = '홍길동'

따라서 o2의 name을 수정하면,

o2의 name만 수정된다.

얕은 복사와 깊은 복사

객체의 참조값을 대입연산자를 통해 복사하는 방법을 얕은 복사, 새로운 객체를 생성하며 속성을 복사하는 방법을 깊은 복사라고 한다.

②객체간 비교는 참조값을 기준으로!

o1과 o2는 참조값이 같으므로 true

o1과 o3는 참조값이 다르기때문에 false

따라서 참조값이 아닌 프로퍼티를 기준으로 객체를 비교하고 싶은 경우 JSON.stringify 함수를 사용하여 비교할 수 있다.

얕은 비교와 깊은 비교

③배열과 함수도 객체이다.

배열과 함수또한 특수한 객체이기 때문에, 일반 객체에 존재하는 프로퍼티와 메서드를 갖는다.

'javascript' 카테고리의 다른 글

[JavaScript - 심화] Spread 연산자와 Rest 매개변수  (0) 2024.11.04
[JavaScript - 심화] 구조 분해 할당  (0) 2024.11.04
[JavaScript - 심화] Truthy와 Falsy  (3) 2024.11.03
'javascript' 카테고리의 다른 글
  • [JavaScript - 심화] Spread 연산자와 Rest 매개변수
  • [JavaScript - 심화] 구조 분해 할당
  • [JavaScript - 심화] Truthy와 Falsy
뜐🐸
뜐🐸
패왕색 패기를 갖춘 뜐입니다~
  • 뜐🐸
    뜐의 개발 로그
    뜐🐸
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 기초 학습
        • HTML
        • CSS
        • JavaScript
        • Version Co..
        • 미니 프로젝트
        • DOM & 웹 AP..
      • CSS 프레임워크
        • Bootstrap
      • React
        • 개념 정리
        • 기초 정리
      • 알고리즘
        • Week 1: 입출..
        • 재귀
        • 백트래킹
      • javascript
      • FastAPI
        • 크롤링 서버 만들기
      • 전역 상태 관리
        • Redux
      • 한 입 리액트 챌린..
      • 영어
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바스크립트 #하노이 탑 #재귀 #백준 # 11729
    inline-block
    :hover
    오블완
    :active
    티스토리챌린지
    백준 #코딩테스트 #1074번 #재귀 #알고리즘 # 알고리즘 문제풀이
    :nth-child(n)
    :focus
    가상 선택자
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
뜐🐸
[JavaScript - 심화] 원시타입과 객체타입
상단으로

티스토리툴바