기술 면접 공부 중 개념이 끝이 없다. 리액트를 사용하지만 어쨌든 기본은 javaScript니까 javaScript 개념 공부를 먼저 하고 있었다. 처음 면접 준비를 하면서 뭐가 이렇게 많은지 끝이 없어서 막막했다. 근데 역시 도움 안되는 건 없다고.. 이래서 사용했구나 를 알 수 있었다.
물론 한 번에 이해 안된다. 하나를 이해하려면 연결된 개념들이 끝이 없다. 근데 신기한 건
일단 보고 이해 안되도 적당히 하고 넘어가기 → 연결된 개념 또 구경하기 → 그러다보니 연결된다.
이렇게 된다..! 그리고 그 끊임없는 개념이라고 생각되는 실행 컨텍스트에 대해 정리해보려 한다. (전문적으로 쓰려 하기 보다 내가 이해한대로 편하게 쓰려 하는 편 🥹 )
javaScript는 변수 선언을 포함한 모든 선언문이 소스코드의 어디에 있든 상관없이 다른 코드보다 먼저 실행 된다. (되는 것 처럼 보인다. 그렇게 해준다? 아무튼 물리적으로 코드를 위로 끌어올린 건 아니다.)
**런타임 이전에 실행컨텍스트에 의해 스코프에 등록 되는데,이 때 마치 코드의 제일 위에 있는 것 처럼! 변수가 어디 있든 상관 없이 어디서든 변수를 참조할 수 있는 것 처럼 만드는 것**을 변수 호이스팅이라고 한다.
🥸 javaScript는 위에서 아래로 코드를 실행한다.
만약 함수가 실행되어야 하는데 아래에 선언된 변수가 필요하다면?
아직 선언이 안됐으니 당연히 참조할 수 없고 실행도 못 하겠다.
아래에서 쓴 게 위에서 필요하기도 하고, 위에서 쓴 걸 함수에 넣었다가 뭐 아래에서 필요하기도 하고 하니까..?
그래서 변수를 위에 있는 것 처럼 해서 참조가 수월하도록 해준다고 생각!
아무튼 호이스팅이 이런건데, 그럼 결국 변수와 같은 정보를 어딘가에 저장을 해야 한다.
이 때 저장을 하는 곳이 환경레코드인거고, 환경레코드는 또 실행 컨텍스트와 연결되어 있는 개념이다.
런타임은 말그대로 실행 시간! 프로그램이 서버에 올라가서 실행 되는 시간이다.
런타임 환경은 이렇게 서버에 올라와서 프로그래밍 언어가 구동 되는 환경!
javaScript 에서 모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다. 얘가 대장이다.
소스코드를 실행하는데 필요한 환경을 제공하고, 실행 결과를 관리해주는 곳.
(코드 실행 할 때 그냥 그 한줄로 실행되지 않는다. 머 this값을 가져와야 한다거나, 함수 실행에 필요한 변수를 찾아서 가져온다거나!? 그니까 코드가 실행되려면 이러한 환경들이 필요한데 이런걸 관리해준다.)
흐름은 크게 이런 식이다.
동일한 환경에 코드들이 있으면, 얘네를 실행하기 위해 필요한 환경 정보들이 있을 것이다. 얘네들을 모아서 객체를 구성한다. 그 객체덩어리를 젠가 나무라고 생각하자. 이 나무막대기들을 콜스택이라는 곳에 쌓아올린다. (코드 실행 순서를 관리하는 곳으로 생각). 콜스택은 젠가처럼 착착 쌓이게 된다. (하나씩 쌓인다!) 그리고 제일 위에 쌓여있는 나무막대기와 관련 있는 코드들이 실행된다.
A 실행하는데 필요한 얘들 모여라 ~~~ -> A막대기 완성
B 실행하는데 필요한 얘들 모여라 ~~~ -> B막대기 완성
C 실행하는데 필요한 얘들 모여라 ~~~ -> C막대기 완성
🥸 야 먼저 만들어진 얘들 일로와서 엎드려.
C (3번째)
B (2번째)
A (1번째)
------이렇게 쌓인다.
🥸 젤 위에 있는 C야, 너네랑 연관된 코드들 머야? 걔네 실행시켜라, 그리고 너넨 사라져.
B (2번째)
A (1번째)
------젤 위에 있는 C가 실행된다.
이 때 실행 컨텍스트가 활성화 되는 시점에 변수가 호이스팅 되는 것!
실행 컨텍스트 스택은 위에서 말한 콜스택!
코드의 실행 순서를 관리해주는 자료 구조이다. 제일 먼저 생긴 나무막대기는 아래로, 그리고 착착 쌓인다. 마지막에 생긴 나무막대기가 제일 꼭대기에 있겠다.
콜스택은 Last In First Out (LIFO)구조로 코드를 관리한다.
젠가도 밑에서부터 빼면 무너진다. 마지막에 쌓아 올린 위에꺼 부터 꺼내서 실행된다.
렉시컬 환경은 또 머냐면,
모든 식별자와 바인딩 된 값, 스코프를 생성, 기록하고 관리하는 자료 구조이다.
스코프를 구분해 식별자를 등록하고, 관리하는 저장소 역할을 한다.
스코프는 또 머냐면,
식별자가 유효한 범위를 말한다. javaScript 는 스코프를 통해 어떤 변수를 참조할 지 결정한다.
🥸 야야 변수가 너무많다, 뭔 변수를 참조해서 이거 실행해야 하는거야?
각 식별자는 지들이 가지고 있는 유효한 범위가 있다. 여기저기 낄 수 없다.
그걸 스코프가 도와주고, 얘네들을 관리하는 환경 자체가 렉시컬 환경이다.
(스코프는 또 전역스코프, 지역스코프, 렉시컬 스코프로 구분된다.)
환경 레코드는 식별자와 식별자에 바인딩 된 값을 기록한다.
그니까 스코프에 포함된 식별자를 등록하고, 등록된 식별자에 바인딩 된 값을 관리하는 저장소!
외부 렉시컬 환경에 대한 참조는 상위 스코프를 가리킨다. (바깥의 환경이라고 생각)
이런 참조를 통해 스코프 체인을 구성한다.
렉시컬 환경아 식별자가 여러갠데 나 변수 뭐 참조해야해?
환경레코드좀 보자. 오 이 식별자에는 이 값이 연결(바인딩)되어 있구나. 이거 가져다 써야하는군.
어 근데 이건 머지? 여기 없넹 밖에 나가서 찾아봐야겠다. (외부 렉시컬 환경 참조)
찾았다. 스코프 체이닝 ㄱㄱ (스코프 합치기)
🥸환경레코드에서 참조, 없으면 외부 렉시컬 환경을 참조해 스코프 체이닝을 통해 식별자를 결정한다.
쓰다보니 이게 맞나 싶지만,, 최대한 쉽게 이해하고자 쓴건데 아니면 다음에 다시 수정하는걸로..