렉시컬 환경(Lexical Environment)과 실행컨택스트

1

실행컨택스트(Execution contedt)

자바스크립트에서는 자바스크립트 엔진이 함수 실행을 하는 문구를 보고 실행 컨택스트를 생성한다.

예시 코드를 보면서 이해해보자.

언제나 그렇듯 예시 코드를 보여서 이해해보자.

function printName(){
  return "put in your name";
}

function findName(){
  //find a(){} for explanaitio lexcial environment
  return printName();
}

function sayMyName(){
  return findName();
}

sayMyname()

먼저, 결과는 어떻게 될까? put in your name이 출력 될 것이다.

아래의 그림처럼 sayMyname()이 실행 되면, 자바스크립트는 먼저 글로벌 컨택스트를 형성하고 그 위에 sayMyname(),findName(),printName() 실행 컨택스트를 형성할 것이다.

그렇다면 저기 global Execution Context에는 뭐가 있을 까? global object 와 this가 포함되어 있을 것이다.

지금 당장 코드를 켜고 아래와 같이 해보자

<!DOCTYPE html>
<html>
  <head>
    <title>show global example</title>
  </head>
  <body>
    <h1>hellooooo~~</h1>
    <script src="index.js"></script>
  </body>
</html>

이렇게 html 만들면 헬~~로로로로 가 웹사이트가 출력될것이다~그리고 빈 index.js파일은 만들고

웹 페이지 개발자 도구에서 this와 window를 치면 우리가 생성한 적은 없지만 글로벌 오브텍트가 만들어져있다.

여기서 winodw는 글로벌인 셈이다. 브라우저에서 글로벌은 window node.js환경내에서는 global 이니까 말이다.

글로벌 실행 컨텍스트 내부에는 global 객체와 this가 포함되어 있다. 하나의 자바스크립트 파일 내에서 선언된 변수, 함수 등은 글로벌 실행 컨텍스트 내부에 존재하는 global 객체의 property가 된다. 이렇게 글로벌 실행 컨텍스트 내부에서 값을 메모리에 할당하는 과정이 코드 실행의 첫번째 phase이다. 두번째 phase는 실제로 코드를 구동시키는 과정이다.

Lexical Environment? 렉시컬 환경이란?

렉시컬 환경은 특정 코드가 작성, 선언된 환경을 의미한다

자바스크립트 표현에 의하면 아래와 같다.

**In javascript, our lexical scope(available data + variables where the function was defined) determines our available variables.** **Not where the function is called(dynamic scope)**

내가 사용하고자 하는 변수, 함수 등이 어떠한 것인가데 따라 사용여부가 달라 질 수도 있기 때문이며 어디에서 선언한 지가 중요한 것이다. ( this의 경우에는 어디서 호출 했는가도 중요하지만 말이다.)

언제나 그렇듯 예시 코드를 보여서 이해해보자. 위의 컨택스트 예시를 똑같이 렉시컬 환경을 표현해보면 아래 그림과 같다.

자바스크립트가 파일을 실행하면 실행 컨택스트가 형성되는데 ,여기서 각가의 실행컨택스트는 개별적인 세상이며 우주로 비유해보면 개별 소우주 행성이라고 할 수 있다. 글로벌이 우주라고 한다면, . sayMyName()는 화성, findName()는 금성, printName() 은 목성처럼 개별 소우주라 할 수 있고 가장 큰 global() 우주 안에 저 3개의 행성이 있는 것이다.

해당 함수는 글로벌 실행 컨택스트 환경내에서 작성되었다고 볼 수 있다. 그렇다면 자바스크립트는 어떻게 sayMyname()이 호출 되고 실행될때, findMyname()과 printName() 을 찾고 실행할 수 있을까?

이 예제에서 보면 렉시컬 환경이 글로벌 실행컨택스트 이기 때문에 글로벌 실행컨택스트(global object)에서 그 함수를 찾아서 실행하게 되는 원리인 셈이다. 즉 전부다 같은 렉시컬 환경에 있기 떄문에 가능하다. 하지만, 만약 find a(){}라는 함수를 findName()에 만들고 실행하면 어떻게 될까? a();로 실행하면 글로벌 렉시컬에서 실행했는데, a의 렉시컬 환경은 findName() 안이기 때문에 접근할 수 없어서 refrence error : a is not defined를 보게 될 것이다.

호이스팅(Hoisting)?

실행컨택스트가 이루어질떄 , 생성단계와 실행단계로 이루어 지는데, 생성단계에서 자바스크립트 엔진이 변수나 함수를 끌어올리는 행위 자체를 호이스팅이라고 할 수 있다.

아래 점선을 기준으로 위에가 생성단계 밑에가 실행단계로 나누어 진다.

함수 선언에는 함수 표현식과 함수 선언식이 있는데, 함수 선언식의 경우는 호이스팅이 되면서 함수 선언 이전에 호출해도 문제가 되지 않는다. 그러나 함수 표현식의 경우에는 변수를 만들고 선언하고 그 할당된 메모리에 함수를 넣어주기 때문에, 호이스팅이 되지 않고, 에러를 만들어 낸다.

자세한 호이스팅은 아래를 참조하도록 하자.

https://www.notion.so/e19e19cd81554cbfbd14b72e297d53c8

참고자료

출처: Advanced javascripts concept in Udemy

호이스팅 이미지 자료: solodoni tistory.

profile
문과생 개발자되다

0개의 댓글