Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
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 31
Tags more
Archives
Today
Total
관리 메뉴

나 개발자 할래요

실행 컨텍스트 본문

개발자 되는 법.../메모...

실행 컨텍스트

개발_자 2024. 12. 12. 13:21

흠.. 항상 참고한 블로그 순으로 올렸는데, 이번은 이해하기 쉬웠던 순으로 올려봅니다.

https://www.zerocho.com/category/JavaScript/post/5741d96d094da4986bc950a0

 

(JavaScript) 실행 컨텍스트 - 클로저와 호이스팅

안녕하세요. 이번 시간에는 범위에 이어 실행 컨텍스트와 클로저에 대해서 살펴보겠습니다. 제가 지난 시간에 실행 컨텍스트가 제일 중요하다고 하면서 강좌를 마쳤습니다. lexical scoping과 이것

www.zerocho.com

 

https://gamguma.dev/post/2022/04/js_execution_context

 

JS Execution Context (실행 컨텍스트) 란?

코어자바스크립트를 읽고 얻은 지식 중 실행 컨텍스트, 콜스택 | JS Execution Context, JS CallStack

gamguma.dev

 

https://inpa.tistory.com/entry/JS-📚-실행-컨텍스트

 

[JS] 📚 자바스크립트 실행 컨텍스트 원리

실행 컨텍스트 ​실행 컨텍스트(Execution Context)는 scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리이다. 실행 컨텍스트를 바로 이해하지 못하면 코드 독해가

inpa.tistory.com

 

https://velog.io/@kados22/FE-기술-면접-실행-컨텍스트가-무엇인가요

 

[FE 기술 면접] 실행 컨텍스트가 무엇인가요?

1️⃣ 실행 컨텍스트(Execution Context)에 대해서 설명해주세요.실행 컨텍스트는 실행 가능한 코드에 제공할 환경 정보를 모아놓은 객체입니다. 해당 객체에는 변수 객체, 스코프 체인, this 정보가

velog.io

 

 

참고한 블로그 중 첫 번째 블로그에서 scopeChain: ['say 변수객체', '전역 변수객체'], 라고 설명해주셨는데,

개발자 도구를 통해 확인해본 결과 다음 사진과 같이 나왔습니다.

스코프 체인은 자기 자신의 스코프(scope)를 제외한 자신과 가장 가까운 변수 객체의 모든 스코프들이라 할 수 있습니다.

 

자세한 내용은 다음 블로그를 참고 하면 좋을 것 같습니다.

https://ljtaek2.tistory.com/140

 

자바스크립트 - 스코프 체인(scope chain)란?

스코프 체인(scope chain)이란? 스코프 체인(Scope Chain)은 일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결(chain)되고

ljtaek2.tistory.com

 


Execution Context(실행 컨텍스트)

실행할 코드에 제공할 환경 정보들을 모아놓은 객체

컨텍스트는 한국말로 번역하면 문맥입니다. 쉽게 코드의 실행 환경이라고 이해하면 됩니다.

 

자바스크립트는 동일한 환경에 있는 환경 정보들을 모은 실행 컨텍스트를 콜스택에 쌓아올린 후 실행하여 코드의 환경과 순서를 보장할 수 있습니다.

 

스택의 경우 FILO (First In, Last Out) 의 구조이기에 순서를 보장, 콜스택 내부에 쌓인 실행 컨텍스트의 정보를 통해 환경을 보장할 수 있는 것!

 

여기서 환경이란 전역공간이 될 수 있고, 함수 즉 함수 내부의 환경이 될 수 있습니다.

실행 컨텍스트는 크게 전역 실행 컨텍스트함수 실행 컨텍스트로 나눌 수 있습니다.

 

전역 실행 컨텍스트

자바스크립트가 처음 실행될 때 생성되는 컨텍스트

 

이 전역 컨텍스트는 프로그램이 종료될 때까지 유지되며, 전역에 선언된 변수나 함수가 모두 포함됩니다. 전역 컨텍스트에서 선언된 변수와 함수는 프로그램 내 어디서든 접근이 가능합니다.

 

기본적으로 자바스크립트는 싱글 스레드이기 때문에, 전역 실행 컨텍스트는 1개만 존재합니다.

 

 

함수 실행 컨텍스트

함수가 호출될 때마다 생성되는 컨텍스트

 

각 함수는 자신만의 실행 컨텍스트를 가지며, 이 컨텍스트 내에서 선언된 변수와 함수는 해당 함수 내에서만 유효합니다. 함수가 종료되면 그 실행 컨텍스트도 함께 사라집니다.

 

 

컨텍스트의 원칙

  • 전역 컨텍스트 생성 후, 함수 호출 시 마다 컨텍스트가 생깁니다.
  • 컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments: 함수 인자, variable: 해당 스코프 변수), scope chain, this 가 생성됩니다.
  • 컨텍스트 생성 후 함수가 실행되는데, 사용되는 변수들은 변수 객체 안에서 값을 찾고, 없다면 스코프 체인을 따라 올라가며 찾습니다.
  • 함수 실행이 마무리되면 해당 컨텍스트는 사라집니다. (클로저 외) 페이지가 종료되면 전역 컨텍스트가 사라집니다.

 

💡

a 함수 내부에서 b 함수를 실행하였기에 b 함수의 환경정보들을 수집, 실행 컨텍스트를 생성, 콜스택에 담습니다. 콜스택 최상단에 b 실행 컨텍스트가 있기에 기존 a 실행 컨텍스트와 관련된 코드의 실행을 일시적 중단합니다.

b 함수가 종료된 후 b 실행 컨텍스트가 콜스택에서 제거되고, 최상단에는 a 실행 컨텍스트가 위치하므로 이전에 중단된 지점부터 코드 진행이 재개됩니다.

 

 

var name = 'zero';

function wow(word) { 
  console.log(word + ' ' + name); // hello zero
}

function say () {
  var name = 'nero'; 
  console.log(name); // nero
  wow('hello'); 
}

say(); 

이 코드가 어떻게 실행되는지 내부를 살펴보면,

 

1. 처음 코드를 실행하는 순간 모든 것을 포함한 전역 컨텍스트가 생깁니다. 모든 것을 관리하는 환경입니다. 페이지가 종료될 때까지 유지됩니다.

'전역 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: ['name', 'wow', 'say'],
  },
  scopeChain: [],
  this: window,
}

 

variable: [{ name: 'zero' }, { wow: Function }, { say: Function }]

 

 

2. say(); 하는 순간 새로운 컨텍스트인 say 함수 컨텍스트가 생성됩니다. 전역 컨텍스트는 그대로 존재합니다.

'say 컨텍스트': {
  변수객체: {
    arguments: null,
    variable: ['name'], // 초기화 후 [{ name: 'nero' }]가 됨
  },
  scopeChain: ['전역 변수객체'],
  this: window,
}

차례로 코드를 실행합니다. variable의 name에 nero를 대입해줍니다. console.log(name);이 실행되면 say 컨텍스트 안에서 name 변수를 찾게 됩니다. 존재하므로 nero가 출력됩니다. 그 다음 wow(’hello’); 를 찾지만 wow 변수를 찾을 수 없으므로 scope chain을 따라 상위 변수 객체인 전역 변수객체에서 찾습니다.

 

 

3. wow 함수가 호출되며 wow 컨텍스트가 생성됩니다.

'wow 컨텍스트': {
  변수객체: {
    arguments: [{ word : 'hello' }],
    variable: null,
  },
  scopeChain: ['전역 변수객체'],
  this: window,
}

여기서 중요한 것은 lexical scoping에 따라 wow 함수의 scope chain은 선언 시 이미 정해져 있습니다. 따라서 say 스코프는 wow 컨텍스트의 scope chain이 아닙니다. console.log(word + ' ' + name); 이 실행되며 word와 name 변수를 wow 컨텍스트에서 찾습니다. word는 arguments에서 찾을 수 있고, name은 wow 컨텍스트에 존재하지 않으므로 scope chain을 따라 전역 변수객체에서 찾습니다. 따라서 zero가 출력됩니다.

wow 함수는 애초에 say 컨텍스트와 일절 관련이 없었던 것입니다. 껄껄

 

 

4. wow 함수가 종료 되며 컨텍스트가 사라지고, say 함수의 실행이 마무리됩니다. 따라서 say 컨텍스트도 사라지고, 마지막 전역 컨텍스트도 사라집니다.

 

 

실행 컨텍스트 내부

'현재 컨텍스트': {
  변수객체: {
    arguments: ,
    variable: ,
  },
  scopeChain: ,
  this: ,
}

실행 컨텍스트 내부엔 Variable Environment, Lexical Environment, this binding이 존재합니다.

 

Variable Environment

현재 컨텍스트 내부

  • 식별자 정보 envirnomentRecord,
  • 외부 환경 정보 outerEnvironmentReference

역할:

  • 함수나 전역 컨텍스트에서 var 변수와 함수 선언을 관리합니다.
  • 변수 초기화 및 할당 이전의 상태를 추적합니다.

특징:

  • var 변수는 호이스팅되어 초기화되기 전에는 undefined로 설정됩니다.
  • 함수 선언은 전체 함수 정의가 변수 환경에 저장됩니다.

 

Lexical Environment

Variable Environment 복사해 사용 → 최신 상태 저장

 

역할:

  • 블록 스코프 변수(let, const)와 현재 스코프에서의 식별자 정보를 관리합니다.
  • 상위 스코프와의 연결을 통해 스코프 체인을 형성합니다.

특징:

  • let과 const는 초기화되기 전에는 **TDZ(Temporal Dead Zone)**에 있습니다.
  • Outer Environment Reference를 통해 상위 스코프에 접근합니다.

 

Environment Record(식별자 정보)

식별자와 식별자에 바인딩된 값이 기록되는 공간

  • 호이스팅
var name = 'zero';
 
console.log(name); // zero
console.log(name ); // undefined
 
var name = 'zero'; 

자바스크립트 엔진이 실행 컨텍스트를 구성할 때 environmentRecord에 식별자의 정보를 수집합니다. 이를 통해 엔진은 함수를 실행하기도 전에 해당 컨텍스트 내부의 변수명을 이미 알고 있습니다.

LexicalEnvironment의 environmentRecord의 경우 해당 컨텍스트 환경에 필요한 식별자와 식별자의 값이 기록되며, 함수 실행 시 실행 컨텍스트가 생성되므로 (함수 실행보다 environmentRecord수집이 먼저 되므로) 변수와 같은 식별자를 끌어올리는 것과 같다 라는 개념의 호이스팅이 생겼습니다.

 

Outer Environment Reference(외부 환경 정보)

현재 호출된 함수가 선언될 당시 Lexical Environment를 참조합니다.

var name = 'zero';

function say () {
  console.log(name);
}

say 함수가 선언 될 당시의 outerEnvironmentReference는 글로벌 실행 컨텍스트의 Lexical Environment를 참조하고 있으며, 해당 환경의 environmentRecord에 name와 같은 변수의 정보가 기록되어 있습니다.

때문에 함수 내부에선 outerEnvironmentReference를 통해 상위 컨텍스트의 Lexical Environment에 접근하여 environmentRecord에서 변수인 name을 사용할 수 있게 되는 것입니다.

 

말이 이해가 안 된다면 노트에 그리면서 이해해 보십셔~..

 

더불어 outerEnvironmentReferenc는 오직 자신이 선언될 당시의 LexicalEnvironment를 참조하기에 순차적으로만 접근이 가능하며, 여러 스코프에서 동일한 식별자를 생성하였다 하더라도 가장 먼저 발견한 식별자만 접근이 가능합니다.

 

This Binding

this는 함수 호출 방식에 따라 달라지는 동적으로 바인딩되는 참조값입니다.

 

this는 자바스크립트에서 현재 실행중인 함수가 참조해야 할 객체를 나타냅니다.

즉, 함수가 어디서 호출되었는지, 어떻게 호출되었는지에 따라 this가 가리키는 값이 달라집니다.

 

핵심 개념

  • this 는 함수 호출 방식에 의해 결정됩니다. (함수 선언 방식과는 무관)
  • 동적 바인딩: this 는 함수를 호출할 때 결정되며, 호출 컨텍스트에 따라 값이 달라집니다.

 

 

this가 전역 객체를 바라보는 경우

1. 일반 함수 호출

function foo() {
  console.log(this); // 전역 객체 (브라우저에서는 `window`, Node.js에서는 `global`)
}
foo();
const bar = function () {
  console.log(this); // 전역 객체
};
bar();

 

2. 중첩 함수

메서드 내부에서 선언된 중첩 함수는 일반 함수처럼 호출되므로, 기본적으로 this는 전역 객체를 참조합니다.

const obj = {
  outer: function () {
    function inner() {
      console.log(this); // 전역 객체
    }
    inner();
  },
};
obj.outer();

 

 

예외 : this 가 전역 객체를 바라보지 않는 경우

1. 메서드 호출

객체의 프로퍼티로 호출된 함수는 그 객체를 this로 참조합니다.

const obj = {
  method: function () {
    console.log(this); // obj
  },
};
obj.method();

 

2. 화살표 함수

화살표 함수는 this가 상위 스코프의 this를 따릅니다.

const obj = {
  outer: function () {
    const inner = () => {
      console.log(this); // obj (상위 스코프의 `this`를 따름)
    };
    inner();
  },
};
obj.outer();

 

3. bind, call, apply로 명시적 this 설정

💡

call: 함수를 호출하면서, 첫 번째 인자로 this를 설정하고 나머지 인자를 넘깁니다.

apply: call과 비슷하지만, 인자를 배열로 넘깁니다.

bind: 새로운 함수를 반환합니다. 반환된 함수의 this는 바인딩된 객체로 고정됩니다.

 

function foo() {
  console.log(this);
}
const obj = { name: 'obj' };

foo.call(obj); // obj
foo.apply(obj); // obj
const boundFoo = foo.bind(obj);
boundFoo(); // obj

 

4. 엄격 모드

엄격 모드에서는 일반 함수 호출 시 this는 undefined입니다.

'use strict';
function foo() {
  console.log(this); // undefined
}
foo();

 

 

핵심 요약

 

실행 컨텍스트

코드 실행 환경을 정의하고 관리하는 객체

 

구성 요소

  • 변수 환경 : var와 함수 선언 관리
  • 렉시컬 환경: 블록 스코프(let, const)와 상위 스코프 참조 관리
  • this 바인딩: 호출 방식에 따라 설정

동작 원리

생성 단계에서 선언된 변수와 함수가 메모리에 올라가고,

실행 단계에서 코드가 순차적으로 실행됩니다.

 

핵심 역할

  • 변수와 함수 접근 관리
  • 스코프 체인을 통해 상위 상위 환경 참조
  • 호출 스택을 통해 실행 흐름 제어

결론적으로, 실행 컨텍스는 자바스크립트 코드 실행의 토대로, 스코프와 this 바인딩 같은 중요한 개념의 동작을 결정합니다.

 

 

 

 

'개발자 되는 법... > 메모...' 카테고리의 다른 글

리액트의 props와 state  (0) 2024.12.18
이벤트 루프  (1) 2024.12.17
tanstack-query의 stale time과 gc time  (1) 2024.12.13
reflow와 repaint의 차이점  (0) 2024.12.11
클로저  (2) 2024.12.09