Skip to content

[week2_MINJAE] 23장 퀴즈#5

Open
mimizae wants to merge 2 commits intomainfrom
week2_MINJAE
Open

[week2_MINJAE] 23장 퀴즈#5
mimizae wants to merge 2 commits intomainfrom
week2_MINJAE

Conversation

@mimizae
Copy link
Collaborator

@mimizae mimizae commented Nov 3, 2025

Q1.

아래 코드의 출력 결과를 쓰시오.
그 이유를 렉시컬 스코프 관점에서 설명하시오.

const x = 10;

function outer() {
  const x = 20;
  function inner() {
    console.log(x);
  }
  return inner;
}

const fn = outer();
fn();

Q2.

아래 코드의 실행 결과를 순서대로 쓰고, 코드 실행 중 실행 컨텍스트 스택(Call Stack)의 변화 과정을 단계별로 설명하시오.

var x = 1;

function first() {
  console.log("first start");
  second();
  console.log("first end");
}

function second() {
  console.log("second");
}

first();

Q3.

아래 코드가 호이스팅(hoisting) 된다면, 자바스크립트 엔진이 실제로 평가 단계에서 어떤 코드 구조로 인식하고 실행하는지 작성하시오.
또한 실행 컨텍스트 생성 시점(평가 단계)과 코드 실행 시점(실행 단계)에서 무슨 일이 일어나는지 간략히 설명하시오.

const x = 1;
const y = 2;

function foo(a) {
  const x = 10;
  const y = 20;

  console.log(a + x + y);
}

foo(100);

console.log(x + y);

Q4.

아래의 코드 실행 시 에러가 발생한다면 어떤 에러인지 쓰고, 자바스크립트 엔진이 inner 실행 시 a, b, c, d를 검색하는 과정을 실행 컨텍스트의 렉시컬 환경 구성 기준으로 단계별로 간략히 설명하시오.

const a = 1;

function outer() {
  const b = 2;
  function middle() {
    const c = 3;
    function inner() {
      console.log(a, b, c, d);
    }
    inner();
  }
  middle();
}

outer();

Q5.

아래의 문제를 푸시오.

(1) 자바스크립트에서 함수가 호출될 때마다 새로운 실행 컨텍스트가 생성된다. (O/X)
(2) 실행 컨텍스트 스택(Call Stack)에서 맨 위(top)에 있는 컨텍스트가 현재 실행 중인 코드의 실행 컨텍스트다. (O/X)
(3) 렉시컬 스코프는 함수가 “호출되는 시점”의 위치를 기준으로 결정된다. (O/X)

@Tnalxmsk
Copy link
Collaborator

Tnalxmsk commented Nov 3, 2025

Q1.
아래 코드의 출력 결과를 쓰시오. 그 이유를 렉시컬 스코프 관점에서 설명하시오.

const x = 10;

function outer() {
  const x = 20;
  function inner() {
    console.log(x);
  }
  return inner;
}

const fn = outer();
fn();

변수 fn에는 outer 함수 호출의 반환값 inener 함수 할당
fn에는 함수 inner가 할당되어 fn() 호출 시 inner 함수 호출
결과적으로 console.log(x) 실행되어
20 출력

스코프는 정의된 위치에 의해 결정 -> 렉시컬 스코프 규칙임. console.log(x)에서 x 평가 시 inner 함수의 렉시컬 환경의 환경 레코드에서 식별자 x를 찾음. 해당 환경 레코드에는 x가 존재하지 않으므로 OuterLexcialEnvironentReference가 가리키는 outer의 렉시컬 환경으로 이동. 해당 렉시컬 환경의 환경 레코드에는 식별자 x가 존재하므로 식별자 검색을 마치고 console.log(20)이 되어 20 출력

fn === inner는 전역에서 호출되었지만 정의는 outer 함수 내부에서 정의되어 있음. 따라서 전역에서 정의된 const x = 10은 전역 렉시컬 환경의 선언적 환경 레코드에 등록되어 있으나 이미 outer 함수의 환경 레코드에 등록된 x를 찾았으므로 스코프 체인을 종료하므로 전역 렉시컬 환경의 선언적 레환경 레코드까지 도달하지 않음

  • inner는 outer의 환경을 캡처한 클로저이므로 outer가 종료된 후라도 x = 20 에접근이 가능

Q2.
아래 코드의 실행 결과를 순서대로 쓰고, 코드 실행 중 **실행 컨텍스트 스택(Call Stack)**의 변화 과정을 단계별로 설명하시오.

var x = 1;

function first() {
  console.log("first start");
  second();
  console.log("first end");
}

function second() {
  console.log("second");
}

first();
first start
second
first end
  1. 전역에서 코드가 실행되어 전역 실행 컨텍스트 생성
  • first 함수를 호출해 전역 코드 실행 중지
  1. first 함수 실행 컨텍스트 생성
  • 코드를 실행하다 second 함수를 호출하고 first 함수 실행 중지
  1. second 함수 실행 컨텍스트 생성 후 코드 실행하고 종료 후 second 함수 실행 컨텍스트가 스택에서 pop

  2. 마지막 console 출력 이후 코드 실행 종료되어 first 함수 실행 컨텍스트 pop

  3. 전역 코드 실행 종료되어 전역 실행 컨텍스트 pop -> 스택 empty

Q3.

아래 코드가 호이스팅(hoisting) 된다면, 자바스크립트 엔진이 실제로 평가 단계에서 어떤 코드 구조로 인식하고 실행하는지 작성하시오. 또한 실행 컨텍스트 생성 시점(평가 단계)과 코드 실행 시점(실행 단계)에서 무슨 일이 일어나는지 간략히 설명하시오.

const x = 1;
const y = 2;

function foo(a) {
  const x = 10;
  const y = 20;

  console.log(a + x + y);
}

foo(100);

console.log(x + y);

전역 객체 생성 이후 전역 코드 평가 단계에 진입. 이때 전역 실행 컨텍스트와 전역 렉시컬 환경을 생성해 전역 렉시컬 환경을 실행 컨텍스트에 바인딩함

위 코드에서 const 키워드로 선언한 변수 x, y는 전역 렉시컬 환경의 선언적 환경 레코드의 식별자로 등록되며 undefined가 초기화되는 것이 아닌 uninitialiezd로 표현됨. 이것은 TDZ에 진입해 있는 것을 의미
그리고 foo 함수는 함수 명을 식별자로 등록하고 함수 객체를 할당함
이후 this 바인딩과 OuterLexicalEnvironmentReference에 대한 참조도 결정하나 설명 생략

이후 전역 코드가 실행되어 foo 함수를 호출함. 호출 시 전역 코드 실행이 중지되고, foo 함수 코드 제어권 받음

foo 함수 실행 컨테스트 생성 및 렉시컬 환경 생성 후 바인딩
foo 함수 또헌 평가 단계에서 환경 레코드에 식별자를 등록하고 실행 단계에서 값을 바인딩함

이후 console.log(a + x + y)에서 console 객체를 찾기 위해 OuterLexicalEnvironmentReference가 참조하는 전역 렉시컬 환경으로 이동해 객체 환경 레코드의 BindingObject를 통해 console 찾고 log 메서드를 찾은 후 a, x, y를 각각 렉시컬 환경과 OuterLexicalEnvironmentReference의 스코프 체인에 따라 각 식별자를 검색함. a, x, y는 각각 파라미터, 지역 변수로 foo 함수의 렉시컬 환경에 등록되어 있으므로 100 + 10 + 20 = 130이 되어 130출력 후 실행 종료

전역 console 또한 동일한 과정 수행 이후 3 출력하고 실행 종료

정리하면 실행 컨텍스트 생성 시점에선 코드 평가가 이루어지며 렉시컬 환경 또한 생성해 실행 컨텍스트에 바인딩함. 이때 해당 평가 단계에서 존재하는 변수, 함수 등을 환경 레코드에 등록하고 실행 단계로 넘어가 환경 레코드에서 식별자를 확인하거나 OuterLexicalEnvironmentReference의 스코프 체인을 통해 거슬러 올라가 확인하는 과정을 거침

Q4.
아래의 코드 실행 시 에러가 발생한다면 어떤 에러인지 쓰고, 자바스크립트 엔진이 inner 실행 시 a, b, c, d를 검색하는 과정을 실행 컨텍스트의 렉시컬 환경 구성 기준으로 단계별로 간략히 설명하시오.

const a = 1;

function outer() {
  const b = 2;
  function middle() {
    const c = 3;
    function inner() {
      console.log(a, b, c, d);
    }
    inner();
  }
  middle();
}

outer();

참조 에러: d 정의 안됨
실행 컨텍스트 순서는 전역 -> outer -> middle -> inner 순
각 컨텍스트는 자신만의 렉시컬 환경을 구성

a 검색

  1. inner 환경 레코드: 없음 -> middle 이동
  2. middle 환경 레코드: 없음 -> outer 이동
  3. outer 환경 레코드: 없음 -> 전역 이동
  4. 전역 : a 존재 a=1 바인딩 찾음

b 검색

  1. inner 환경 레코드: 없음 -> middle 이동
  2. middle 환경 레코드: 없음 -> outer 이동
  3. outer: b 존재 b=2 바인딩 찾음

c 검색

  1. inner 환경 레코드: 없음 -> middle 이동
  2. middle: c 존재 c=3 바인딩 찾음

d 검색

  1. inner 환경 레코드: 없음 -> middle 이동
  2. middle 환경 레코드: 없음 -> outer 이동
  3. outer 환경 레코드: 없음 -> 전역 이동
  4. 전역: 없음. 스코프 체인의 끝이므로 ReferenceError 발생

렉시컬 스코프는 정의 위치에의 정해지기 때문에 inner -> middle -> outer -> global 순으로 스코프 체인 연결
각 렉시컬 환경의 OuterLexicalEnvrionmentReference는 상위 스코프를 가리킴
위와 같은 스코프 체인을 통해 식별자를 검색하며 최종적으로 d를 찾지 못했기 때문에 참조에러 발생

Q5.
아래의 문제를 푸시오.

(1) 자바스크립트에서 함수가 호출될 때마다 새로운 실행 컨텍스트가 생성된다. (O)

(2) 실행 컨텍스트 스택(Call Stack)에서 맨 위(top)에 있는 컨텍스트가 현재 실행 중인 코드의 실행 컨텍스트다. (O)

(3) 렉시컬 스코프는 함수가 “호출되는 시점”의 위치를 기준으로 결정된다. (X)

@qowjdals23
Copy link
Collaborator

Q1.
출력 결과 : 20
이유:

  • inner 함수는 outer 함수 내부에서 정의되었기 때문에, inner가 실행되어 변수 x를 찾을 때에는 자신이 정의된 위치를 기준으로 상위 스코프를 탐색한다. inner 내부에는 x가 없으므로 바로 상위 스코프인 outer의 렉시컬 환경에서 const x=20을 발견한다. 전역의 x=10은 탐색 대상이 아니다.
  • outer()가 실행되면 inner 함수가 반환되고, 전역에서 fn()를 호출할 때도 inner는 여전히 outer의 스코프에 접근할 수 있기 때문에 20을 출력한다. (inner는 outer의 변수 환경을 기억하는 클로저로 동작)

Q2.
결과:

second
first end
  • 코드가 실행되면 가장 먼저 전역 실행 컨텍스트가 생성되어 스택에 쌓인다.
  • 그 후 first() 한수가 호출되며, first의 실행 컨텍스트가 생성되고 스택 위에 쌓인다.
  • first 함수가 시작되면서 "first start"를 출력한 뒤, 내부에서 second() 함수를 호출하면서 second의 실행 컨텍스트가 새로 생성되고 스택의 최상단에 위치한다.
  • second함수가 실행되며 "second"가 출력되고, 실행 종료와 함께 스택에서 제거된다.
  • 다시 first 컨텍스트로 돌아와 "first end"를 출력하고, 실행이 종료되면 first 컨텍스트도 스택에서 제거된다.
  • 마지막으로 전역 실행 컨텍스트도 종료되며 스택은 비워진다.

Q3.

평가 단계

  • 전역 실행 컨텍스트가 생성되어 전역 렉시컬 환경이 구성된다.
  • foo 함수 선언이 함수 객체로 생성되고, 전역 스코프에 등록된다.
  • const x, const y 가 전역 환경에서 선언되지만 아직 초기화되지 않은 TDZ 상태이다.
  • foo의 상위 스코프(Outer LExical Environment Reference)는 전역 렉시컬 환경으로 결정된다.

실행 단계

  • 전역의 x=1, y=2가 초기화된다.
  • foo(100)을 호출하면 새로운 함수 실행 컨텍스트가 생성되고, 스택에 push 된다. 지역 스코프에서 x=10, y=20이 초기화되고, console.log(a+x+y)가 실행되어 100+10+20= 130 이 출력된다.
  • foo 실행 종료 후 전역으로 돌아와 colsole.log(x+y)가 실행 되어 1+2=3이 출력된다.

Q4.
결과:
ReferenceError

  • inner가 호출되면 inner의 실행 컨텍스트가 생성되고, 현재 렉시컬 환경의 Environment Record에는 a,b,c,d가 존재하지 않기 때문에 Outer Lexical Environment Reference를 따라 바깥으로 올라가며 찾는다.(스코프 체인)
  • a 검색 : inner: Environment Record 없음 -> middle: Environment Record 없음 -> outer: Environment Record 없음 -> 전역 렉시컬 환경에서 const a=1 발견 -> a=1
  • b 검색 : inner: Environment Record 없음 -> middle: Environment Record 없음 -> outer Environment Record에서 const b=2 발견 -> b=2
  • c 검색: inner: Environment Record 없음 -> middle: Environment Record에서 const c=3 발견 -> c=3
  • d 검색 : inner: Environment Record 없음 -> middle: Environment Record 없음 -> outer: Environment Record 없음 -> 전역 Lexical Environment 없음 -> 모든 렉시컬 환경에서 찾을 수 없음 -> 식별자 결정 실패 => ReferenceError 발생

Q5.

(1) 자바스크립트에서 함수가 호출될 때마다 새로운 실행 컨텍스트가 생성된다. (O)
(2) 실행 컨텍스트 스택(Call Stack)에서 맨 위(top)에 있는 컨텍스트가 현재 실행 중인 코드의 실행 컨텍스트다. (O)
(3) 렉시컬 스코프는 함수가 “호출되는 시점”의 위치를 기준으로 결정된다. (X)
-> 정의된 위치를 기준으로 결정

Copy link
Member

@jstar000 jstar000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q1.

출력 결과: 20

전역 코드 평가 과정에서 전역 객체와 전역 실행 컨텍스트, 전역 Lexical Environment가 생성되고, x, outer, fn이 전역 Lexical Environment에 등록된다.
전역 코드가 실행되면 x에 10이 할당되고, const fn = outer() 코드가 실행된다.
이때 outer 함수가 호출되고, outer 함수 내부로 코드 제어권이 이동하며 함수 코드 평가에 의해 outer 함수의 실행 컨텍스트와 함수 Lexical Environment가 생성된다.
함수 Lexical Environment에는 xinner가 등록되고, 리턴문에 의해 outer 함수가 종료되며 코드 제어권이 전역 코드로 되돌아가고 fn에는 inner 함수가 반환된다.
전역 코드의 fn()문이 실행된다. 이는 사실상 inner 함수의 호출과 같으며, inner 함수 실행 컨텍스트와 Lexical Environment가 생성되고 console.log(x) 구문이 실행된다.
자바스크립트에서 상위 스코프는 렉시컬 스코프(상위 스코프가 동적으로 변하지 않고 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정)에 의해 결정된다. 따라서 변수 x의 검색 과정에서 스코프 체인에 의해 상위 스코프인 outer 함수의 Lexical Environment로 이동하고, outer 함수의 Environment Record에 등록된 x를 찾아 최종적으로 20을 출력한다.

Q2.

실행 결과:
first start
second
first end

  1. 전역 코드 평가와 실행
    JS 엔진이 전역 코드를 평가하며 전역 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시함

  2. first 함수가 실행되며 first 함수 코드 평가와 실행 진행
    first 함수 코드가 실행되며 코드 제어권이 전역 코드에서 first 함수로 이동하며, JS 엔진은 first 함수 내부의 함수 코드를 평가하며 first 함수 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시함

  3. second 함수가 실행되며 second 함수 코드 평가와 실행 진행
    second 함수 코드가 실행되며 코드 제어권이 first 함수에서 second 함수로 이동하며, JS 엔진은 second 함수 내부의 함수 코드를 평가하며 second 함수 실행 컨텍스트를 생성하고 실행 컨텍스트 스택에 푸시함.

  4. console.log("second") 출력 후 second 함수 실행이 종료되며 실행 컨텍스트 스택에서 pop됨

  5. 코드 제어권이 다시 first 함수로 돌아가며, first 함수의 console.log('first end') 출력 후 first 함수 실행이 종료되며 실행 컨텍스트 스택에서 pop됨

  6. 코드 제어권이 다시 전역 코드로 돌아오며, 더이상 실행할 코드가 없으므로 전역 실행 컨텍스트가 싨행 컨텍스트 스택에서 pop됨

Q3.

전역 객체가 생성되고 전역 코드 평가 과정에서 전역 실행 컨텍스트와 전역 Lexical Environment가 생성됨. const 키워드로 선언된 변수인 x와 y는 전역 Lexical Environment의 Declarative Environment Record에 uninitialized 상태로 등록되고, foo 함수는 Object Environment Record에 등록되며 등록과 동시에 함수 객체로 초기화됨
전역 코드 실행 과정에서 uninitialized 상태였던 x와 y에 각각 1, 2라는 값이 할당된 후 foo 함수가 실행됨. 이때 코드 제어권이 전역 코드에서 foo 함수 내부로 이동하며, foo 함수의 코드 평가가 시작되고 foo 함수 실행 컨텍스트와 foo 함수 Lexical Environment가 생성됨. 함수 내부의 x, y는 함수 Environment Record에 uninitialized 상태로 등록됨.
함수 코드 실행 과정에서 uninitialized 상태였던 x와 y에 각각 10, 20이라는 값이 할당된 후 console.log(a + x + y) 코드가 실행됨. console 키워드는 스코프 체인을 통해 전역 스코프로 이동한 후 전역 객체에서 찾고, x와 y는 스코프 체인의 시작지점인 foo 함수의 Lexical Environment에서 찾음. 변수 a는 현재 스코프에서 찾을 수 없으므로 OuterLexicalEnvironmentReference에 등록된 스코프인 상위 스코프, 즉 전역 스코프로 이동해 변수 a를 탐색하는데, Global Environment Record에서도 해당식별자를 찾을 수 없으므로 ReferenceError가 발생함.
그 뒤에 전역 코드의 console.log(x+y)가 정상적으로 실행된다고 가정한다면 x와 y라는 식별자를 현재 스코프인 전역 Lexical Environment에서 검색하며, 이미 선언과 할당이 끝난 x, y값을 찾을 수 있으므로 3이 출력됨.

Q4.

전역 객체가 생성되고, 전역 코드 평가 과정에서 const 키워드로 선언된 변수인 a가 전역 Lexical Environment(Declarative Environment Record)에 등록, outer 함수는 Object Environment Record에 등록됨
outer 함수가 실행되고, outer 함수의 실행 컨텍스트와 Lexical Environment가 생성되며 변수 b와 함수 middle이 outer 함수 Environment Record에 등록됨.
middle 함수가 실행되고, middle 함수의 실행 컨텍스트와 Lexical Environment가 생성되며 변수 c와 함수 inner가 middle 함수 Environment Record에 등록됨.
inner 함수가 실행되고, console.log(a, b, c, d)에서 변수 a, b, c, d의 검색을 시작함.
스코프 체인에 의해 현재 Lexical Environment에서부터 식별자를 찾기 시작하고, 검색에 실패할 시 Lexical Environment의 OuterLexicalEnvironmentReference로 상위 스코프로 이동하며 해당 Lexical Environment에서 식별자를 찾는 과정을 반복함.
식별자 a, b, c는 각각 전역, outer, middle의 Lexical Environment에서 찾을 수 있으며, 식별자 d는 스코프 체인을 통해 전역 Lexical Environment까지 이동했음에도 찾을 수 없으므로 ReferenceError가 발생함.

Q5.

(1) (O)
(2) (O)
(3) (X), 자바스크립트에서 상위 스코프는 렉시컬 스코프(상위 스코프가 동적으로 변하지 않고 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정)

@sonnnnhe
Copy link
Collaborator

sonnnnhe commented Nov 4, 2025

Q1

출력 결과: 20

자바스크립트는 렉시컬 스코프(정적 스코프)로 선언된 위치에 따라 상위 스코프가 정해진다.
따라서 inner 함수의 상위 렉시컬 환경은 outer 함수 렉시컬 환경, outer 함수의 상위 렉시컬 환경은 전역 렉시컬 환경이 되는 것이다.

fn() 으로 인해 outer 함수가 호출되고 return inner 로 인해 inner 함수가 실행되는데, inner 함수 내부의 console.log(x); 코드 실행 시 x 식별자 결정이 진행된다. 식별자 검색은 'inner 렉시컬 환경 -> 실패 -> outer 함수 렉시컬 환경 -> 성공'의 과정을 거치므로 20이 출력된다.


Q2

실행 결과

first start
second
first end

전역 코드 평가가 시작되면서 실행 컨텍스트 스택에 전역 실행 컨텍스트가 push 된다.
전역 코드 평가가 끝난 후 전역 코드가 순차적으로 진행되고 first() 코드를 만나 식별자 first 검색에 성공하여 first 함수를 호출하며 first 함수 코드 평가가 시작된다.
함수 렉시컬 환경이 완성되면 실행 컨텍스트 스택에 first 실행 컨텍스트가 push 되고 코드 평가가 끝난 뒤 first 함수 코드가 실행된다. 순차적으로 실행되다 second() 코드를 만나 식별자 second를 상위 렉시컬 환경에서 검색에 성공하고 second 함수를 호출하며 second 함수 코드 평가가 시작된다.
first 함수와 같은 방식으로 second 실행 컨텍스트가 실행 컨텍스트 스택에 push되고 second 함수 코드가 실행된다.
second 함수 코드 실행이 종료되어 실행 컨텍스트 스택에서 second 실행 컨텍스트가 pop되어 제거되고 first 실행 컨텍스트가 최상위가 되어 실행 중인 실행 컨텍스트가 된다.
이후 first 함수 코드 실행이 종료되어 실행 컨텍스트 스택에서 first 실행 컨텍스트가 pop되어 제거되고 전역 실행 컨텍스트가 최상위가 되어 실행 중인 실행 컨텍스트가 되며, 전역 코드 실행 종료 시 전역 실행 컨텍스트도 실행 컨텍스트 스택에서 pop되어 제거되어 실행 컨텍스트 스택에 아무것도 남아있지 않게 된다.

전역 실행 컨텍스트 push -> first 실행 컨텍스트 push -> second 실행 컨텍스트 push -> second 실행 컨텍스트 pop -> first 실행 컨텍스트 pop -> 전역 실행 컨텍스트 pop


Q3

전역 객체 생성 후 전역 코드 평가를 시작한다.
전역 실행 컨텍스트를 생성하여 실행 컨텍스트 스택에 push하고 전역 렉시컬 환경을 생성하여 전역 실행 컨텍스트에 바인딩한다.
이때 전역 렉시컬 환경의 객체 환경 레코드에는 식별자 foo가 함수 객체 자체로 초기화되어 할당되고 선언식 환경 레코드에는 식별자 x, y가 초기화되지 않은 상태로 할당되어 TDZ에 빠진다.

이후 전역 코드가 실행되며 식별자 x, y에 값이 할당되어 TDZ에서 벗어나게 되고 foo(100);을 만나 foo 함수가 호출되며 foo 함수 코드 평가가 시작된다.
foo 실행 컨텍스트 생성 후 foo 함수 렉시컬 환경을 생성하여 식별자 x, y와 매개변수 a를 초기화되지 않은 상태로 환경 레코드에 등록하고(TDZ) 평가가 끝난 뒤 foo 함수 코드를 실행한다.
매개변수에 인수가 할당되고 변수 할당문이 실행되어 지역 변수 x, y에 각각 10, 20의 값을 할당된다.
console.log(a + x + y);의 표현식을 수행하기 위해 식별자 a, x, y 검색을 시작하고 전부 foo 렉시컬 환경에서 검색에 성공하여 130이 출력된다.

이후 foo 함수 코드가 종료되어 실행 컨텍스트 스택에 foo 실행 컨텍스트가 pop되고 전역 실행 컨텍스트가 실행 중인 실행 컨텍스트가 되어 console.log(x+y);를 수행한다.
식별자 x, y가 전역 렉시컬 환경에서 검색 성공하여 3이 출력된다.


Q4

Reference Error

각 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 의해
inner -> middle -> outer -> 전역 의 형태로 연결되어 있다.

a 검색
inner 환경 레코드 검색 -> 실패 -> middle 환경 레코드 검색 -> 실패 -> outer 환경 레코드 검색 -> 실패 -> 전역 환경 레코드 검색 -> 성공

b 검색
inner 환경 레코드 검색 -> 실패 -> middle 환경 레코드 검색 -> 실패 -> outer 환경 레코드 검색 -> 성공

c 검색
inner 환경 레코드 검색 -> 실패 -> middle 환경 레코드 검색 -> 성공

d 검색
inner 환경 레코드 검색 -> 실패 -> middle 환경 레코드 검색 -> 실패 -> outer 환경 레코드 검색 -> 실패 -> 전역 환경 레코드 검색 -> 실패
더 이상 참조할 상위 스코프가 없으므로 ReferenceError


Q5

(1) O
(2) O
(3) X

@Sohyunnnn
Copy link
Collaborator

Q1.

아래 코드의 출력 결과를 쓰시오.

그 이유를 렉시컬 스코프 관점에서 설명하시오.

const x = 10;

function outer() {
  const x = 20;
  function inner() {
    console.log(x);
  }
  return inner;
}

const fn = outer();
fn();
20

렉시컬 스코프는 함수가 어디서 호출되었는지가 아니라, 어디서 정의되었는지에 따라 상위 스코프가 결정되는 규칙

  1. inner 함수는 outer 함수 내부에서 정의되었기 때문에,

    outer의 렉시컬 환경을 기억한다.

    즉, inner의 상위 스코프는 outer 스코프.

  2. 따라서 inner 실행 시,

    x를 현재 스코프(inner)에서 찾지 못함 → outer 스코프에서 x = 20을 찾음 → 전역의 x = 10은 탐색되지 않음.

Q2.

아래 코드의 실행 결과를 순서대로 쓰고, 코드 실행 중 **실행 컨텍스트 스택(Call Stack)**의 변화 과정을 단계별로 설명하시오.

var x = 1;

function first() {
  console.log("first start");
  second();
  console.log("first end");
}

function second() {
  console.log("second");
}

first();
first start
second
first end
  1. 전역 코드 평가 및 실행
    • 전역 실행 컨텍스트(Global Execution Context) 생성 → Call Stack에 push
    • 전역 스코프에 x, first, second 식별자 등록
  2. first() 호출
    • first() 함수의 실행 컨텍스트 생성 및 push
    • 전역 실행은 일시 중단되고, first 함수로 제어권 이동
  3. second() 호출
    • second 함수 실행 컨텍스트 생성 및 push
    • console.log("second") 실행 → "second" 출력
    • 함수 종료 후 pop
  4. first() 계속 실행
    • "first end" 출력
    • first() 종료 → 실행 컨텍스트 pop
  5. 전역 코드로 복귀
    • 전역 코드의 실행이 끝나면 전역 실행 컨텍스트도 pop되어 Call Stack이 비워짐.

Q3.

아래 코드가 호이스팅(hoisting) 된다면, 자바스크립트 엔진이 실제로 평가 단계에서 어떤 코드 구조로 인식하고 실행하는지 작성하시오.

또한 실행 컨텍스트 생성 시점(평가 단계)과 코드 실행 시점(실행 단계)에서 무슨 일이 일어나는지 간략히 설명하시오.

const x = 1;
const y = 2;

function foo(a) {
  const x = 10;
  const y = 20;

  console.log(a + x + y);
}

foo(100);

console.log(x + y);
130
3

자바스크립트는 코드를 실행하기 전에, 먼저 선언문만 끌어올려(hoisting) 스코프에 등록

이때 function은 전체가 호이스팅되고, const/let은 선언만 올라가며 TDZ에 들어감.

(1) 전역 코드 평가

  • 전역 실행 컨텍스트 생성
  • 전역 렉시컬 환경이 구성됨
    • Environment Record
      • const x (TDZ)
      • const y (TDZ)
      • function foo (함수 객체로 바로 초기화됨)
  • 이 시점에 foo는 호출 가능하지만 x, y는 TDZ에 있으므로 아직 접근 불가.

(2) 전역 코드 실행

  • x = 1, y = 2 → TDZ 해제, 초기화 완료
  • foo(100) 호출 → 새로운 함수 실행 컨텍스트 생성

(3) foo 함수 평가

  • 새로운 렉시컬 환경 생성

    • a = 100 (매개변수)
    • x (TDZ)
    • y (TDZ)
  • 이후 코드 실행 시점에서

    x = 10, y = 20으로 초기화

(4) foo 함수 실행

  • console.log(a + x + y) 실행

  • 현재 함수 스코프(foo) 내에서

    a=100, x=10, y=20130 출력

  • foo 실행 종료 → 컨텍스트 pop

(5) 전역 코드 계속 실행

  • console.log(x + y) 실행
  • 전역 스코프의 x=1, y=23 출력
  • 전역 코드 종료 → 전역 컨텍스트 pop

Q4.

아래의 코드 실행 시 에러가 발생한다면 어떤 에러인지 쓰고, 자바스크립트 엔진이 inner 실행 시 a, b, c, d를 검색하는 과정을 실행 컨텍스트의 렉시컬 환경 구성 기준으로 단계별로 간략히 설명하시오.

const a = 1;

function outer() {
  const b = 2;
  function middle() {
    const c = 3;
    function inner() {
      console.log(a, b, c, d);
    }
    inner();
  }
  middle();
}

outer();
ReferenceError

inner() 함수 내부에서 존재하지 않는 식별자 d를 참조하려 하기 때문에 ReferenceError 가 발생.

  1. inner 실행 컨텍스트 생성
    • inner()가 호출되면 새로운 함수 실행 컨텍스트가 생성됨.
    • inner렉시컬 환경(Lexical Environment) 이 만들어지고, Outer Lexical Environment Referencemiddle 함수의 렉시컬 환경을 가리킴.
    • inner 내부에는 자체 선언된 식별자가 없음.
  2. console.log(a, b, c, d) 실행 → 식별자 결정 시작
    • 엔진은 각 식별자를 현재 렉시컬 환경에서부터 차례로 검색.
    • 찾지 못하면 Outer Lexical Environment Reference를 따라 상위 스코프로 이동.
  3. 식별자별 검색 경로
  • a

    inner X → middle X → outer X → 전역 환경에서 발견 (a = 1)

  • b

    inner X → middle X → outer 환경에서 발견 (b = 2)

  • c

    inner X → middle 환경에서 발견 (c = 3)

  • d

    inner X → middle X → outer X → 전역 X

    모든 렉시컬 환경에 존재하지 않음 → ReferenceError 발생

Q5.

아래의 문제를 푸시오.

(1) 자바스크립트에서 함수가 호출될 때마다 새로운 실행 컨텍스트가 생성된다. (O)

(2) 실행 컨텍스트 스택(Call Stack)에서 맨 위(top)에 있는 컨텍스트가 현재 실행 중인 코드의 실행 컨텍스트다. (O)

(3) 렉시컬 스코프는 함수가 “호출되는 시점”의 위치를 기준으로 결정된다. (X)

@eunkr82
Copy link
Collaborator

eunkr82 commented Nov 4, 2025

A1.

[실행 결과] 20
JS에서 스코프는 함수가 어디에서 정의되었는지를 기준으로 결정되는데, 이를 렉시컬 스코프라고 한다.
inner 함수는 outer 안에서 정의되었으므로 inner 함수의 상위 스코프는 outer 함수 스코프다.
따라서 inner 안에서 x를 검색할 때, inner -> outer 내부의 x=20을 찾아 출력한다.

A2,

[실행 결과]

first start
second
first end
  1. 전역 컨텍스트
    전역 코드가 평가 후 실행된다.
  2. first 컨텍스트
    first()가 호출되고, 새로운 실행 컨텍스트가 생성되며 이 실행 컨텍스트가 스택에 푸시된다.
  3. second 컨텍스트
    second()가 호출되면 새로운 실행 컨텍스트가 생성되며 이 실행 컨텍스트가 스택에 푸시된다.
  4. 실행 완료 후 종료 단계
    second -> first -> 전역 순으로 실행이 완료되면 스택에서 pop된다.
    스택이 비워지면 프로그램이 종료됨에 따라 전역 컨텍스트도 제거된다.

A3.

const x = 1;
const y = 2;

function foo(a) {
  const x = 10;
  const y = 20;

  console.log(a + x + y);
}

foo(100);

console.log(x + y);
  1. 평가 단계
  • 전역 실행 컨텍스트가 생성된다.
  • 함수 선언문 foo가 등록된다.
  • const x, y 선언은 등록되나 값은 할당되지 않고 TDZ에 들어간다.
  1. 실행 단계
  • const x, const y에 값이 할당된다.
  • foo(100)이 실행되면 코드의 제어권이 foo에게로 넘어가고, 새로운 실행 컨텍스트가 생성된다.
  • foo 내부에서 다시 x=10, y=20 지역 변수가 초기화된다.
  • console.log문이 평가되고, 생성된 값은 다시 console.log문으로 전달된다. (130 출력)
  • 함수가 종료되면 지역 컨텍스트는 제거된다. (pop)
  • console.log(x + y); 의 x와 y는 전역 변수를 의미한다. 3이 출력된다.

A4.

ReferenceError
inner 함수 내부에서 a, b, c, d가 존재하지 않으므로 상위 환경으로 이동해야 한다. middle에 x, outer에 b, 전역에 a가 존재하나 d는 어디에도 존재하지 않으므로 참조 에러가 발생한다.

A5.

  1. O
  2. O
  3. X

@mimizae
Copy link
Collaborator Author

mimizae commented Nov 4, 2025

정답 노션 링크 첨부합니다! 아자잣!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants