잘못된 부분이 있으면 지적 부탁드립니다.
컴퓨터가 프로그램을 실행하는 과정을 간단히 해보면 네단계를 거친다
위의 프로그램 실행 플로우에서 CPU가 데이터를 RAM 메모리에 올려줄때
스코프와 변수 선언, 참조 등 다양한일이 벌어진다
메모리는 크게 4가지 영역으로 구분할수 있다
코드 영역
데이터 영역
힙 영역
스택 영역
자바스크립트에서의 자료형들은 크게 원시 타입
과 참조 타입
으로 구분이 가능하다. 자바스크립트는 원시값을 제외한 모든것이 참조형 객체이다
원시값
은 프로그래밍 언어에서 미리 사용할 수 있도록 만들어준 데이터인데
String
, Number
, Boolean
, Undefined
, Symbol
, Bigint
그리고 Null
값이 원시값에 해당하고 이 외의 모든 데이터들은 다 객체타입으로 사용된다
원시타입과 객체타입의 가장 큰 차이점은, 값의 변경이 가능한지대한 여부이다 이를 가변성(mutable)
과 불변성(immutable)
이라 부른다
원시값(primitive value)들은 자바스크립트에서 제공해준 값들이 조합(숫자, 문자열, undefined 등)이므로 메모리의 공간을 얼마나 사용할지가 사전에 정의가 가능하다. 하지만 객체 리터럴의 경우, 동적으로 확장이 가능해서 메모리상에 얼만큼 할당해주어야 하는지 알수가 없다.
따라서 자바스크립트는 원시값과 객체를 다른 방식으로 관리한다
원시 값의 특징은 immutable
이다. 이는 원시값이 자바스크립트가 실행될때 제공하는 원시 값 데이터를 활용하기때문이다. 어떤 원시값을 변수에 할당하면, 변수에는 실제 값이 복사
되어 저장되고 다른 변수가 원시값을
갖고 있는 변수를 값으로 할당하면, 언본의 원시값이 복사되어 전달된다.
title = 'deepDive
처럼 이미 선언되어있는 변수에 새로운 원시값을 할당할 경우(재할당
), 자바스크립트는 새로운 메모리 공간에 새로 할당되는 값을 입력하고, 기존에 사용하던 변수명이 이를 가리키게 한다. 이때 이전에 할당되어진 값은 가리키고 있는 변수가 하나도 없으므로 가비지 컬렉터에의해 해제가 된다.
위의 title = 'deepDive
처럼 문자열은 부분 수정이 안되는 불변성을 갖고있어서 변경이 필요한 경우 재할당을 해야한다
let str = 'abcd';
console.log(str[3]) // d
str[3] = 'a'; // 부분 수정을 시도하지만
console.log(str) // 'abcd' 변하지 않는다
자바스크립트의 문자열은 특이하게도 문자열이면서 동시에 유사 배열객체이기에 length 메소드도 활용이 가능 하다. 가능한 이유는 문자열 데이터 타입에 배열 메소드를 활용하게되면 자바스크립트가 자동으로 String 객체 래퍼로 문자열을 감싸주기 때문이다. 따라서 문자열은 유사 배열 객체이면서
이터러블(순회가 가능)함으로 배열과 유사하게 각 문자에 접근 할수 있다
ler str = 'hi';
console.log(str[0]) // 이때 String 객체래퍼로 문자열이 감싸진다
// String(str) === {0: 'h', 1:'i'} 가 되고
// String(str)[0] === 'h'가 된다
원시 값은 이미 제공되는 primitive data들을 활용해서 immutable한 특징을 갖고 있다. 반면 참조값은 객체 값이고 프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가되고 삭제될수 있다. 그렇기때문에 객체는 원시값과 같이 메모리 공간의 크기를 사전에 정해둘수 없고 동적으로 관리된다
자바스크립트는 객체를 생성하게 될때, 힙 메모리에 객체 인스턴스를 생성하고, 이
인스턴스가 존재하는 위치를 스택 메모리에 기록하여 사용한다.
이러한 특징때문에 객체를 변수에 할당하게 되는 경우, 변수는 해당 객체가 메모리상에 존재하는 주소를 참조하게 된다.
변수를 선언하고 사용할때 메모리에서 어떤식으로 할당이 되는지와 문자열의 불변성은 평소에 전혀 생각하지 못했던 부분이였다.
팀 러버덕 리더 훈님 자료
모던 자바스크립트 deep dive 11장
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management#garbage_collection