FE RYAN
완벽하지 않으면 어때
FE RYAN
전체 방문자
오늘
어제

블로그 메뉴

  • 💾 깃허브 링크
  • 홈
  • 태그
  • 분류 전체보기 (151)
    • 개인프로젝트 (8)
      • 개인 포트폴리오 웹앱 (6)
      • 프론트엔드 기술면접 아카이빙 웹앱 (2)
    • 기록 (121)
      • 원티드 프리온보딩 인턴십 (0)
      • 코드스테이츠 프론트엔드 (75)
      • 생각들 (3)
      • Today I learned (32)
      • 회고 (9)
      • 리뷰 (1)
    • 개발 (17)
      • React (3)
      • Javascript (7)
      • CSS (1)
      • HTML (3)
      • HTTP (1)
      • 자료구조 (0)
      • 알고리즘 (2)
    • 코딩테스트 (2)
      • 백준 (2)
      • 프로그래머스 (0)
    • 디자인 (1)
      • UI & UX (1)
    • 수학 (0)
    • 자기계발 (0)

공지사항

인기 글

태그

  • seb 39
  • ES6
  • 코드스테이츠
  • 자바스크립트 딥다이브
  • Til
  • 리액트
  • HTML
  • 원시타입
  • seb39
  • 자바스크립트
  • 프론트엔드
  • css
  • useMemo
  • 메인프로젝트
  • 타입스크립트
  • 포트폴리오
  • 부트캠프
  • 회고
  • 딥다이브
  • 신입개발자

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
FE RYAN

완벽하지 않으면 어때

개발/Javascript

[자바스크립트] 원시 타입과 참조 타입

2022. 5. 12. 17:18
728x90

참고자료

  • 모던 자바스크립트 딥 다이브 서적 11장 - 원시 값과 객체의 비교
  • 메모리 영역에서의 heap과 stack
  • 신입 개발자 전공 지식 & 기술 면접 백과사전

원시 값과 참조 값의 비교

  • 자바스크립트에서 제공하는 7가지 데이터 타입(숫자, 문자열, 불리언, null, undefined, symbol, 객체) 중에서 객체를 제외한 나머지 6개 모두 원시 타입이다.

원시 타입과 객체 타입의 가장 큰 차이점 3가지

  1. 원시 값은 변경 불가능한 값(immutable value)이다. 참조 값은 변경 가능한 값(mutable value)이다.
  2. 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 객체를 변수에 할당하면 참조 값이 저장된다.
    1. 주의: 변수에 값이 저장되는 것이 아니라 해당 변수(식별자)와 name binding 된 메모리 공간에 값이 저장되는 것임. (변수란 하나의 값을 저장하기 위해 확보한 메모리 공간 자체, 또는 그 공간(메모리)을 식별하기 위해 붙인 이름(=스택에 붙인 이름표: 변수명)이다.)
  3. 값에 의한 전달(=복사) vs 참조에 의한 전달(=참조):
    1. 값에 의한 전달: 원시 값을 가진 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다.(깊은복사)
    2. 참조에 의한 전달: 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.(얕은복사)
  • 값에 의한 전달: pass by value, 참조에 의한 전달: pass by reference

참조: 변수에 저장된 값을 읽어 들이는 것

// 원시 값
// 원시 값의 deep copy 예시
// 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.
let a = 1;
let b = 2;
b = a; // b = 2 -> 1
b = 3; // b = 1 -> 3

console.log(a); // 1
console.log(b); // 3
// 원본 a의 복사본인 b의 값이 재할당 되더라도 원본의 값에 영향을 미치지 않음.

// 참조 값
// 참조 타입의 값은 힙 영역에 저장되며 저장된 데이터의 주소값(참조값)은 스택 영역에 생성되어 변수는 스택 영역에 저장됨.
// 현재 원본 배열(객체)인 arr1을 참조하고 있는 arr2는 서로 같은 주소값을 변수에 담고 있으므로 비교 시 true를 반환한다.
// 참조 자료형의 엄격한 비교(===)는 원시 값 끼리의 비교처럼 값 자체를 비교하는 게 아니라
// '주소값'이 같은지를 확인하는 것이다.
let arr1 = [1, 2, 3];
let arr2 = arr1;
console.log(arr1 === arr2); // true

// 참조 값의 shallow copy 예시
// 원본 객체인 ryan의 복사본인 tom을 수정하였으나 원본에도 수정한 내용이 동일하게 반영됨.
let ryan = { age : 10 };
let tom = ryan; // tom = { age : 10 }
tom.hobby = 'riding';

console.log(ryan.hobby); // riding
tom; // {age: 10, hobby: 'riding'}
ryan; // {age: 10, hobby: 'riding'}

1. 원시 값(primitive data type)

1.1 원시 값은 변경 불가능한 값(immutable value)이다.

불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.(딥다이브 p139)

변수 ≠ 값

  • 변수와 값을 구분하여 생각하여야 한다.
    • 변수: 값을 저장하기 위해 확보한 메모리 공간 자체, 또는 그 메모리 공간을 식별하기 위해 붙인 이름
    • 값: 표현식이 평가되어 생성된 결과. (ex: 2 + 2; 라는 표현식은 평가되어 4 라는 값을 가진다.)
  • 원시 값 자체를 변경할 수 없다 ≠ 변수 값을 변경할 수 없다
    • 변수는 언제든지 재할당을 통해 변수 값을 교체할 수 있다.

즉 원시 값은 변경 불가능한 값이기 때문에 값 자체를 변경할 수는 없지만 재할당으로 값을 새로 ‘교체’하여 값을 변경한 것과 같은 행동을 할 수 있다.

이 때, 새로 재할당된 값은 새로운 메모리 공간에 저장되고 이전에 할당된 값은 원래의 메모리 공간에 그대로 남아 있으나 어떠한 식별자(변수, 함수, 클래스)에도 연결(name binding)이 되어 있지 않으므로 사용할 수 없는 쓰레기 값이 된다.

이러한 값들은 자바스크립트 엔진이 가비지 컬렉터로 더이상 사용되지 않는 메모리를 해제해주지만 그 시점이 언제일지는 알 수 없다. 이러한 불필요한 쓰레기 값들이 발생하고 있는 상태를 메모리 누수 라고 한다.

name binding: 변수 이름과 확보된 메모리 공간의 주소를 연결하는 행위

2. 참조 값(reference data type)

  • 객체는 데이터의 크기가 얼마든지 줄어들거나 커질 수 있다. (동적으로 추가되고 삭제가 가능)
  • 참조 값: 생성된 객체가 저장된 메모리 공간의 주소 그 자체(reference value)

2.1 참조 타입은 변경 가능한 값이다.

객체는 변경 가능한 값이다. 따라서 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.

  • 객체를 가진 변수가 가지고 있는 메모리 주소값(참조 값)이 힙(실제 객체의 프로퍼티를 담은 메모리 공간)의 주소값이다.
    • 따라서 “변수는 객체를 가리키고(참조하고) 있다” 라고 표현한다.
// 상수인 const는 변수의 일종이기에 값을 할당할 수 있으나 재할당은 어떤 경우에도 불가능하다.
// 하지만 참조 값(객체)은 재할당 없이 값을 추가하거나 삭제, 또는 갱신할 수 있으므로,
// 상수에서도 객체의 경우 값의 변경이 가능하다. 원시 타입은 재할당만 할수 있으므로 불가능!

const user = {
	name : 'Ryan'
};

// 재할당 없이 프로퍼티 값 갱신 가능
user.name = 'Kim';

// 프로퍼티 동적 생성(새로운 프로퍼티 추가)
user.age = 16;

console.log(user); // {name: 'Kim', age: 16}

정리

  • 원시 값이던 참조 값이던 변수에 저장되는 것은 값 자체가 아니라 변수와 연결된 메모리 공간의 주소값이다.(딥다이브 p 145)
  • 원시 값을 가진 변수의 메모리 공간에는 값 자체가 저장된다.
  • 참조 값을 가진 변수의 메모리 공간에는 힙(실제 객체 데이터가 저장된 메모리 공간)의 주소값이 저장된다.
  • 따라서 원시 값끼리 동등 비교시(===) 원시 값은 값 끼리 비교, 참조 값은 주소 값끼리 비교한다.
728x90
저작자표시 비영리 변경금지

'개발 > Javascript' 카테고리의 다른 글

[자바스크립트] 호이스팅, 스코프, 클로저, spread, rest, 구조분해할당  (0) 2022.05.16
모던 자바스크립트 딥 다이브 7장 연산자 내용 정리  (0) 2022.05.16
[자바스크립트] 모던 자바스크립트 딥 다이브 5장 표현식과 문 내용정리  (0) 2022.05.08
[자바스크립트] 모던 자바스크립트 딥 다이브 4장 변수 내용 정리  (0) 2022.05.08
[자바스크립트] 고차함수와 콜백함수(작성중)  (0) 2022.04.28
    '개발/Javascript' 카테고리의 다른 글
    • [자바스크립트] 호이스팅, 스코프, 클로저, spread, rest, 구조분해할당
    • 모던 자바스크립트 딥 다이브 7장 연산자 내용 정리
    • [자바스크립트] 모던 자바스크립트 딥 다이브 5장 표현식과 문 내용정리
    • [자바스크립트] 모던 자바스크립트 딥 다이브 4장 변수 내용 정리
    FE RYAN
    FE RYAN

    티스토리툴바