[ JS ] 변수 재정의 시, 메모리 구조

jwkwon0817·2024년 12월 22일
0

Language

목록 보기
3/3
post-thumbnail

JavaScript는 변수명 리터럴을 실행 컨텍스트 (Execution Context)라는 곳에 저장한다.

예를 들어 아래와 같은 코드를 짰다고 가졍하면,

var name = 'Jeewon';

실행 컨텍스트에는 아래와 같은 정보가 들어간다

ExecutionContext = {
  VariableEnvironment: {
    name: <reference to '0x00001'>
  }
}

0x00001 주소를 가진 메모리에는 'Jeewon'이라는 값이 저장되어있다.


만약 아래와 같이 name을 재정의 한다면?

name = 'Sunrin';

일반적으로 생각했을 때는 0x00001 주소의 값이 'Sunrin'으로 바뀔 거라고 생각하지만 JS는 그렇게 동작하지 않는다.
새로운 메모리 공간을 할당(예시로 0x00008로 함.)하고 실행 컨텍스트에서 name이라는 변수가 참조하고 있는 메모리 주소를 바꾼다.

현재 실행 컨텍스트

ExecutinoContext = {
  VariableEnvironment: {
    name: <reference to '0x00008'>
  }
}

현재 메모리 상태

Variable NameAddressValue
0x00001'Jeewon'
name0x00001'Sunrin'

그리고 JavaScript의 GC(Garbage Collector)가 변수명 리터럴이 지정되지 않은 메모리는 할당 해제하게 된다.

위와 같은 방법으로 자바스크립트는 변수명과 메모리를 관리한다.

아래와 같은 코드가 있을 때

let age = 17;

function addAge(a) {
  a += 1;
}

addAge(age);

console.log(age); // 17 or 18?

정답은 17이다.

실행 컨텍스트에서의 age는 메모리 주소를 참조하지만 실제로 코드 상에서는 값을 넘기기 때문에 원본 값이 바뀌지 않는 것이다.
이를 C언어와 같은 포인터가 있는 언어에 빗대어서 설명하자면 그냥 void 함수에 일반적인 int 변수를 넘겼을 때 값이 변하지 않는 것과 같은 원리이다.

그러면 아래 코드는 어떻게 동작할까?

let me = {
  name: 'Jeewon',
  age: 17
}

function addAge(obj) {
  obj.age += 1;
}

addAge(me);

console.log(me.age); // 17 or 18?

이 경우에는 age의 값이 18이다.
왜냐하면 자바스크립트에서 일반적인 원시타입의 변수는 아까 말한것처럼 값을 내포하지만 객체는 실제로 메모리 주소를 참조하고 있어서 그렇다. me가 참조하고 있는 메모리 주소를 예시로 0x00001이라고 하면 me도 0x00001을 참조하고 있고 그 메모리 주소를 인자로 받은 obj 파라미터도 똑같이 0x00001 메모리 주소를 참조하고 있어서 함수 내에서 프로퍼티 값을 바꿔도 정상적으로 동작한다. 이를 C언어와 빗대어 설명하면 파라미터로 포인터 변수를 넘기는 것과 같은 원리다.

profile
SRIHS 119th SW

0개의 댓글

관련 채용 정보