일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 자바 기초
- 자바
- Openjdk
- Display
- Heidi
- react
- 웹디자인 기능사
- 연산자
- 전자정부프레임워크
- do while
- overflow
- HTML
- 자바 환경변수
- float
- java
- CSS
- position
- Break Continue
- vue
- 조건문
- To Do List
- 자료형
- DropDown
- 로또 번호 생성
- javascript
- clear
- JS
- mysql
- db
- switch
- Today
- Total
잠온다
JS) 자바스크립트의 메모리 할당, 실행 컨텍스트와 콜 스택 본문
며칠 전에 객체의 속성에 값을 할당하다가 문제가 생겼다.
foo2에 test.foo1를 할당할 땐 test를 읽지 못하지만, 함수를 할당할 땐 에러가 나지 않는 것이다.
스크립트를 읽어들이면서 foo2에 test.foo1을 할당할 시점에는 객체 test가 아직 다 그려진 상태가 아니기에, 즉 test는 undefined 이기에 foo2: undefined.foo1과 같은 형태가 되면서 에러가 난다고 생각했다.
그렇다면 func2에서는 왜 test는 undefined로 읽히지 않아서 func2: function() { undefined.fun1(); } 과 같은 형태가 되지 않는 것일까?
1. 실행 컨텍스트(Execution Context)
실행 컨텍스트란, 자바스크립트 코드가 실행되고 연산되는 범위를 나타내는 추상적이 개념을 말한다.
일종의 코드가 실행되는 환경이라고 생각하면 쉬운데, 실행 컨텍스트는 크게 전역 실행 컨텍스트(Global Execution Context)와 함수 실행 컨텍스트(Function Execution Context)로 나뉜다.
브라우저의 자바스크립트 엔진은 스크립트를 만나면 우선 전역 컨텍스트를 생성하며, 그 후 엔진이 함수를 호출할 때마다 함수 실행 컨텍스트를 생성한다. 이때 생성된 실행 컨텍스트는 콜 스택에 쌓인다.
2. 콜 스택(Call Stack)
콜 스택은 원시 타입의 데이터나 참조 타입 데이터의 주소 값이 저장되는 자료 구조다. 코드가 실행되면서 생성되는 실행 컨텍스트 또한 참조 타입 데이터(객체)이므로, 이를 가리키는 주소 값이 스택에 저장된다. 중요한 점은 코드가 실행되면서, 즉 호출될 때 메모리에 값이 할당된다는 점이다.
3. 실행 컨텍스트의 구조
실행 컨텍스트는 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이지만, 물리적으로는 객체의 형태를 가지며 Variable Object(VO / 변수 객체), Scope chain, this Value라는 3가지 프로퍼티를 소유한다.
3-1. Variable Object(VO / 변수 객체)
JS 엔진 실행에 필요한 여러 정보들을 담은 객체로, 코드가 실행될 때 엔진에 의해 참조되며 코드에서는 접근할 수 없다. Variable Object는 변수, 매개변수(parameter), 인자(argument), 함수 선언 정보를 담는다. (함수 표현식은 제외)
Variable Object는 실행 컨텍스트의 프로퍼티로 객체 값을 가지는데, 전역 컨텍스트는 스크립트가 처음에 읽히면서 생성되기에 매개변수가 없다.
4. 분석
지금까지의 정보를 종합하자면 아래와 같은 결론이 나오고 그렇기 때문에 foo2에서 에러가 발생하는 것이다.
// 1.
// 전역 실행 컨텍스트 생성
// 2. 변수 선언, 초기화 단계
var test = undefined; // 호이스팅
test = {
foo1: "localhost:8080",
foo2: undefined.foo1,
func1: {/* function object */}, // 함수 선언식 정보만 담는다.
func2: {/* function object */},
}
좀 더 알기 쉬운 형태로 변환하자면...
var test = undefined;
var foo1 = "localhost:8080";
var foo2 = undefined.foo1;
var func1 = {/* function object */};
var func2 = {/* function object */};
test = {/* 객체 주소값 생성 -> 위 변수(속성)들로 객체 초기화 */};
// test.func1이나 test.func2가 호출된다면
function test.func1() {
// ...
}
test.func1();
function test.func2() {
// ...
}
test.func2();
'Javascript' 카테고리의 다른 글
JS) this, bind (0) | 2023.01.08 |
---|---|
JS) DOM, node, element, reflow, repaint (0) | 2023.01.04 |
JS) 자주 사용하는 ES6 문법 (0) | 2022.07.02 |
JS) var, let, const, 호이스팅 (1) | 2022.06.19 |
JS) 함수와 함수의 호출, (2) | 2022.06.19 |