string의 메모리 공간

사전 지식 : Primitive Type과 Reference Type

원시 타입의 string은 값의 길이에 따라 메모리 공간의 크기가 달라지는데, JS는 변하는 문자열을 어떻게 저장할까?

문자열은 유사 배열 객체이면서 이터러블이다. 하지만, 배열이 아니고 원시값이기 때문에 변경할 수 없다(물론 재할당은 가능하다)

image.png

따라서 문자열을 재할당하는 경우에는, 새로운 문자열 객체를 생성하고, 변수는 해당 객체를 가리킨다.

즉, 기존 메모리 주소에 있던 값을 변경하는 것이 아니고, 새로운 메모리 공간을 마련하고 그 안에 문자열을 넣는다.

Pass by Value는 값을 전달하는 것이 아니다

보통 primitive type을 복사할땐 pass by value라는 단어를 사용하지만, 엄격하게는 값을 전달하는 것이 아니라, 메모리 주소를 전달한다. 단, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.

const x = 10; // x -> 0x000000F2 메모리 주소에 10을 저장함

let copy = x; // copy -> 0x00001332 메모리 주소에 0x000000F2의 값을 읽어서 가져옴

객체의 저장 방식

JS 객체는 동적으로 프로퍼티가 정해지기 때문에, 메모리 공간을 미리 잡아둘 수 없다.

자바스크립트 객체는 프로퍼티 키를 인덱스로 사용하는 해시 테이블(hash table)이라고 생각할 수 있다. 대부분의 자바스크립트 엔진은 해시 테이블과 유사하지만 높은 성능을 위해 일반적인 해시 테이블보다 나은 방법으로 객체를 구현한다.

image.png

자바스크립트는 클래스 없이 객체를 생성할 수 있으며 객체가 생성된 이후라도 동적으로 프로퍼티와 메서드를 추가할 수 있다. 이는 사용하기 매우 편리하지만 성능 면에서는 이론적으로 클래스 기반 객체지향 프로그래밍 언어의 객체보다 생성과 프로퍼티 접근에 비용이 더 많이 드는 비효율적인 방식이다.

따라서 V8 자바스크립트 엔진에서는 프로퍼티에 접근하기 위해 동적 탐색(dynamic lookup) 대신 히든 클래스(hidden class)라는 방식을 사용해 C++ 객체의 프로퍼티에 접근하는 정도의 성능을 보장한다. 히든 클래스는 자바와 같이 고정된 객체 레이아웃(클래스)과 유사하게 동작한다.