본문 바로가기
개념 정리/모던 자바스크립트 딥다이브

모던 자바스크립트 : 원시값과 객체의 비교

by 매진2 2023. 11. 1.
728x90

원시타입과 객체 타입의 차이에 대해서

  원시 타입 값 객체 타입 값
변경 유무 변경 불가능한 값 변경 가능한 값
변수(확보된 메모리 공간)에 할당 변수에 실제 값 저장 변수에 참조값 저장
복사 값에 의한 전달
: 다른변수에 할당하면 원본의 원시값이 복사되어 전달됨
참조에 의한 전달 :
다른변수에 할당하면 원본의 참조값이 복사되어 전달

1. 원시값이란?

a. 변경 불가능한 값

a-1. 원시값

원시 타입의 값은 변경불가능한 값, 한번 생성된 원시값은 읽기 전용 값으로 변경 불가능

 

a-2. 변수

하나의 값을 저장하기 위해 확보한 메모리 공간 자체

변수는 언제든지 재할당을 통해 변수 값을 변경할 수 있음

 

a-3. 

변수에 저장된 데이터

변경불가능 한 값은 변수가 아니라 값에 대한 것

원시값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 것이 아님!!

 

a-4. 상수

상수는 재할당이 금지된 변수=단 한번만 할당 가능

상수도 값을 저장하기 위한 메모리 공간이 필요하므로 변수라고 할 수 있음

상수!=변경 불가능한 값

 

a-5. 불변성

원시 값 할당한 변수에 새로운 원시 값 재할당 -> 새로운 메모리 공간 확보 후 재할당한 원시 값 저장 후 새롭게 재할당한 원시 값 가리킴

변수가 참조하던 메모리 공간의 주소가 변경된 이유 : 변수에 할당된 원시값이 변경 불가능한 값이기 때문

불변성 갖는 원시 값을 할당한 변수는 재할당 외에 변수값을 변경할 수 있는 방법 없음

만약!! 재할당 외에 다른 방법으로 변수 값을 변경할 수 있다면 예상치 못하게 값이 변경될 수 있다, 추적이 어렵다 

 

b. 문자열과 불변성

b-1. 문자열

  • 문자열은 0개 이상의 문자로 이뤄진 집합
  • 1개의 문자는 2바이트의 메모리 공간에 저장됨
  • 문자열은 몇개의 문자로 이뤄졌느냐에 따라 필요한 메모리 공간의 크기 결정

b-2. 숫자 값

  • 1도 1000000도 동일한 8바이트의 메모리 공간이 필요함

 

b-3. 문자열은 유사배열 객체이면서 이터러블이라서 배열과 유사하게 문자에 접근 가능

  • 이미 생성된 문자열의 일부 문자를 변경하려는 코드에도 에러가 없지만 읽기 전용 값이기 때문에 변경 불가능
  • 원시값은 어떤 일이 있어도 불변, 예기치 못한 변경에서 자유로움, 데이터의 신뢰성 보장

b-4.유사배열 객체

  • 유사 배열 객체는 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체
  • 문자열은 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티 갖기 때문에 유사배열 객체이고 for문 가능
  • 원시값을 객체처럼 사용하면 원시값을 감싸는 래퍼 객체로 자동 변환됨

c. 값에 의한 전달

  • 값에 의한 전달 : 변수에 원시값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시값이 복사되어 전달되는 것
  • 하지만 score 변수와 copy 변수의 값 80은 다른 메모리 공간에 저장된 별개의 값
  • 값에 의한 전달이 이뤄진 후 score 값을 변경하면 copy 변수의 값에는 영향이 없음

***파이썬은 같은 원시값을 가진 경우 같은 값을 참조하다가 하나가 다른 값 가지면 그때 새로운 메모리 공간에 재할당된 값을 저장

***자바스크립트는 내부 동작을 알려주지 않아서 어떻게 작동할지 확실히 모름

***값의 의한 전달이라는 용어는 자바스크립트 용어가 아님

     - 식별자는 값이 아닌 메모리 주소를 기억 => 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달

 

2. 객체

객체

  • 객체는 프로퍼티 개수가 정해져 있지 않고 동적으로 추가, 삭제 가능하며 프로퍼티 값에도 제약이 없음
  • => 객체는 확보해야할 메모리 공간의 크기를 사전에 정할 수 없음
  • 객체는 복잡한 자료구조이므로 객체를 관리하는 방식이 원시값보다 복잡 + 브라우저 제조사마다 다름

자바스크립트 객체 관리 방식

  • 객체는 프로퍼티 키를 인덱스로 사용하는 해시테이블(연관배열)
  • 자바스크립트는 클래스없이 객체 생성 가능 + 객체 생성 이후에 동적으로 프로퍼티와 메서드 추가 가능
    • 사용은 편리하지만 성능면에서는 클래스 기반 객체지향 프로그래밍 언어의 객체보다 생성과 프로퍼티 접근에 비용이 더 많이 드는 비효율적인 방식
    • V8 자바스크립트 엔진에서는 프로퍼티에 접근하기 위해 히든 클래스 라는 방식을 사용해 C++ 정도의 성능 보장
    • 히든 클래스는 자바와 같이 고정된 객체 레이아웃(클래스)과 유사하게 동작

a. 변경 가능한 값

 

a-1. 객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조값에 접근 가능

  • 참조 값은 생성된 객체가 저장된 메모리 공간의 주소, 그 자체
  • 객체를 할당한 변수에는 생성된 객체가 실제로 저장된 메모리 공간의 주소가 저장되어있고 이 값을 참조값이라고 함
  • 변수는 이 참조 값을 통해 객체에 접근 

a-2. 객체(참조) 타입의 값은 변경 가능한 값

  • 객체는 변경가능한 값이기 때문에 재할당 없이 객체를 직접 변경 가능
  • 재할당 없이 프로퍼티를 동적으로 추가, 프로퍼티 값 갱신, 프로퍼티 삭제 가능
  • 재할당을 하지 않기때문에 객체를 할당한 변수의 참조 값은 변경되지 않음
  • 변경 가능하게 설계한 이유
    • 객체는 크기가 클 수도 있고 크기가 일정하지 않고 프로퍼티 값이 객체일 수 있기 때문에 복사해서 생성하는 비용 ↑
    • 메모리를 효율적으로 사용하기 위해 객체 복사 생성 비용 절약해 성능 향상 시키기 위함

a-3. 여러개의 식별자가 하나의 객체를 공유할 수 있다.

얕은 복사와 깊은 복사로 생성된 객체는 원본과는 다른 객체

  • 원본과 복사본은 참조 값이 다른 별개의 객체

얕은 복사

  • 한단계 까지만 복사
  • 객체에 중첩되어 있는 객체의 경우 참조값을 복사
  • 원시값을 할당한 변수를 다른 변수에 할당하는 것

깊은 복사

  • 객체에 중첩되어 있는 객체까지 모두 복사
  • 객체에 중첩되어 있는 객체의 경우 모두 복사해서 원시값처럼 완전한 복사본을 만든다
  • 객체를 할당한 변수를 다른 변수에 할당하는 것

b. 참조에 의한 전달

b-1. 참조에 의한 전달

  • 객체를 가리키는 변수(원본)를 다른 변수(사본)에 할당하면 원본의 참조값이 복사되어 전달되는 것

자바스크립트에는 포인터가 존재하지 않기때문에 포인터가 존재하는 다른 프로그래밍 언어의 참조에 의한 전달과 의미가 정확히 일치하지는 않음

 

b-2. 원본 person과 사본 copy는 저장된 메모리 주소는 다르지만 동일한 참조 값을 가짐

  • 동일한 참조 값을 가짐= 동일한 객체를 가리킴 = 두개의 식별자가 하나의 객체 공유
  • 원본 또는 사본 중 어느 한 쪽에서 객체를 변경하면 서로 영향을 주고 받음
    • 변수에 새로운 객체 재할당 말고 프로퍼티값 변경, 추가, 삭제의 경우만

b-3. 예제

① false

  • person1과 person2가 가리키는 객체는 내용은 같지만 다른 메모리에 저장된 별개의 객체 = 변수의 참조 값이 전혀 다른 값

② true

  • 프로퍼티 값을 참조하는 person1.name과 person2.name은 값으로 평가되는 표현식이며 원시값 Lee로 평가됨

 

 

 

 

모던 자바스크립트 딥다이브 책을 정리한 내용입니다!!!
728x90