본문 바로가기
Books/모던 JS Deep Dive ✔️

[모던 JS Deep Dive] 11장 - 원시 값과 객체의 비교

by Aaron-Kim 2021. 12. 10.

11.0 원시 값과 객체의 비교

 - 원시 값은 immutable value, 객체는 mutable value

 - 원시 값을 변수에 할당하면 변수(확보된 메모리 공간)에는 실제 값이 저장됨

   객체를 변수에 할당하면 변수에는 참조 값이 저장됨

 - 원시 값을 갖는 변수를 다른 변수에 할당 시 원본의 원시 값이 복사되어 전달됨

   => 값에 의한 전달 (pass by value)

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

   => 참조에 의한 전달 (passs by reference)

11.1 원시 값

 - 변경 불가능한 값

   - immutable value

   - 한번 생성된 원시 값은 read only value로서 변경 불가

   - 변수가 아닌 값에 대한 진술 (변수는 언제든지 값 교체 가능, 상수는 불가)

   - 상수는 재할당이 금지된 변수일뿐 변경 불가능한 값과 다름

   - 데이터의 신뢰성 보장

   - 불변성

   - 만약 primitive type이 mutable이면 상태 변경 추적하기 어려워짐

 - 문자열과 불변성

   - ECMAScript 사양 - 문자열 타입 (2바이트), 숫자 타입 (8바이트), 그 이외는 브라우저 벤더마다 다름

   - 문자열은 문자들의 집합, 1개의 문자는 2바이트 메모리 공간에 저장됨

   - 문자열은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근 가능

   - 원시 값인 문자열이 객체처럼 동작함

     - ex) str.length, str.toUpperCase() // 원시 값을 감싸는 래퍼 객체로 자동 변환됨

   - 문자열은 원시 값이므로 문자열 내부 문자에 대한 값 변경 불가 (에러 발생 X)

 - 값에 의한 전달

   - 원시 값 복사 시 두 변수의 값은 같지만 서로 다른 메모리 공간에 저장된 별개의 값임

   - 기존 값 변경해도 복사된 변수 값에는 영향 주지 않음

   - JS 엔진 구현 제조사에 따라 실제 내부 동작 방식 미묘한 차이 가능

     - 파이썬은 원시 값 복사 시 두 변수가 같은 값 가리키다가 복사된 값 저장하는 변수에 값 재할당 시 식별자 이동

   - pass by sharing (공유에 의한 전달) 이라고 표현하는 경우도 있음

   - 엄밀히 말하면 변수는 값이 아니라 메모리 주소를 기억하고 있음 (식별자는 메모리 주소에 붙인 이름)

   - 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 어느 한쪽에서 재할당을 통해

     값을 변경하더라도 서로 간섭할 수 없음

11.2 객체

 - 객체는 사전에 메모리 공간의 크기를 정해둘 수 없음

 - JS 객체 관리 방식

   - 프로퍼티 키를 인덱스로 사용하는 해시 테이블(associative array, map, dictionary, lookup table) 구조

   - JS는 클래스 없이 객체 생성 가능, 객체 생성 이후 동적으로 프로퍼티와 메서드 추가 가능

   - V8 엔진에서는 dynamic lookup (동적 탐색) 대신 hidden class 라는 방식 사용 => 프로퍼티 접근 성능 보장

 - 변경 가능한 값

   - mutable value

   - 참조 값 접근 (참조 값은 Heap에 생성된 객체가 저장된 메모리 공간 주소)

   - 객체는 재할당 없이 객체를 직접 변경 가능 (동적으로 프로퍼티 추가, 프로퍼티 값 갱신, 삭제 가능)

   - 객체를 생성하고 관리하는 방식은 매우 복잡하고 비용이 많이 듦 => mutable

     - 객체를 immutable로 한다면 메모리 효율적 소비가 어렵고 성능 나빠짐

   - 구조적 단점의 부작용

     - 여러 개의 식별자가 하나의 객체 공유할 수 있음

   - 얕은 복사 vs. 깊은 복사

     - 얕은 복사: 객체를 프로퍼티 값으로 갖는 객체의 경우 한 단계까지만 복사

       - cf. 참조 값 복사

     - 깊은 복사: 객체에 중첩되어 있는 객체까지 모두 복사

       - cf. 원시 값 복사

 - 참조에 의한 전달

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

   - 두 개의 식별자가 하나의 객체 공유

     - 어느 한쪽에서 객체 변경하면 서로 영향 주고 받음

   - 엄밀히 말하면 참조에 의한 전달은 존재하지 않고 값에 의한 전달만 존재 (원시 값, 참조 값)

   - JS에는 포인터 존재 X

   - 객체 리터럴은 평가될 때마다 객체 생성

반응형

댓글