programming language/javascript

Context 란?

공대키메라 2021. 8. 31. 22:01

내가 공부하고자 하는 전반적인 내용이 아래 블로그에 담겨있다.

 

https://poiemaweb.com/js-execution-context

 

Execution Context | PoiemaWeb

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

poiemaweb.com

솔직히 나는 글을 정리하는게 너무 귀찮아서 남이 잘 적은 글을 보는 편이다 ㅋㅋ 

 

Context란 뭘까?

 

사실 javascript공부하면서 context라는 단어를 필자는 처음 듣는다 ㅋㅋ(부끄...)

 

context하면 맥락이라는 뜻이다. 사전을 보면 그렇게 명명되있는데

 

출처 : 네이버 사전

 

Context를 이제 javascript에서 뜻을 보면 

 

코드의 배경이 되는 조건, 환경 정도를 뜻한다.

 

이러한 동일한 조건 / 환경을 지니는 코드 뭉치가 있다고 할 때 

 

이 코드 뭉치를 실행할 때 필요한 조건이나 환경 정보가 있다

 

이것을 실행 컨텍스트(Execution Context)라고 명명한다!

 

 

자 솔직히... 개념은 개념이고 ... 개발자는 직접 쳐봐야 하는거 아입네까? 물론 개념도 중요하지 아암~

출처 : 구글 x나좋군?

 

그러면 즐거운 코드시간~

 

내가 적은 코드의 실행 순서를 한번 보자

var a = 1;
function outer(){
    console.log(a);
    function inner(){
        console.log(a);
        var a = 3;
    }
    inner();
    console.log(a);
}

outer();

console.log(a);

 

내 생각에는 음... 

 

글쎄?

 

 

근데 순서가 위처럼 된다넹... 호잉?

 

 

순서는 다음 그림을 보면 왼쪽에서 오른쪽으로 안으로 안으로 들어가면서 실행이 되고 

 

가장 안쪽의 inner() 함수가 가장 빠르게 끝난다고 한다. 

 

위와 같은 자료 구조를 스택이라 한다

 

여기서 우리가 많이 들어봤음직한 Call Stack 이 나온다. 

 

Call Stack이란

 

현재 어떤 함수가 동작중인지, 다음에 어떤 함수가 호출될 예정인지 들을 제어하는 자료구조

 

 

그림으로 보면 이런 식으로 될것이다

 

양동이에 담겨있어서 꺼낼때는 가장 늦게 실행된 것이 먼저 끝나는 방식이다!

 

이 내부를 보면 이러한 구조로 이루어 져있다고 한다. 

 

variableEnvironemt => 오직 식별자 정보를 수집하는 용도로 쓰임

LexicalEnvironment =>  각 식별자의 데이터를 추적하는 용도로 쓰임

두개의 차이는 값의 변화가 실시간으로 변영되느냐, 그렇지 않느냐의 차이만 있다.

 

컨텍스트 내부 코드들을 실행하는 동안에

변수의 값들에 변화가 생기면 그 값이 Lexical Environment에만 실시간으로 반영이 된단다.

 

Lexical Environment를 그럼 한 문장으로 정리하면

 

실행컨텍스트를 구성하는 환경 정보들을 모아 사전처럼 구성한 객체를 의미한다.

 

이 Lexical Environment안에는

 

environmentRecord / outerEnvironmentReference가 존재한다.

 

1. environmentRecord

 

현재 문맥의 식별자 정보가 수집된다.

 

실행 컨텍스트가 최초로 실행될 때 제일 먼저 수집을 한다는데

 

현재 컨텍스트의 식별자 정보들을 수집해서 environmentRecord에 담는 과정을 Hoisting 이라고 한다. 조금 다르지만 많이 비슷하다고 한다.  => 식별자의 정보를 맨 위로 실행시 끌어온다는 점이 비슷!

 

호이스팅에 대한 설명을 한번 찾아봣다

 

https://gmlwjd9405.github.io/2019/04/22/javascript-hoisting.html

 

[JavaScript] 호이스팅(Hoisting)이란 - Heee's Development Blog

Step by step goes a long way.

gmlwjd9405.github.io

//처음 
console.log(a());
console.log(b());
console.log(c());

function a(){
	return 'a';
}

var b = function bb(){
	return 'bb';
}

var c = function(){
	return 'c';
}

//실행하면
//////////////----environmentRecord 부ㅡ분!! 필요한 정보를 먼저 끌어온다!
function a(){
	return 'a';
}
var b;
var c;
////////////----
console.log(a());
console.log(b());
console.log(c());

b = function bb(){
	return 'bb';
}

c = function(){
	return 'c';
}

위의 코드를 

 

실행 컨텍스트가 처음 생성되는 순간 environment에 정보들을 수집하는데 현재 컨텍스트에서 선언되어 있는 식별자들

 

이 무엇이 있느냐라는 정보를 코드 순서대로 수집하다보니 호이스팅하고 같은 개념이 된단다. 

 

하여간 environmentRecord는 예시처럼 정보를 미리 수집하는 역할을 한다!

 

2. outerEnvironmentReference

 

"외부 환경에 대한 참조"라고 해석할 수 있다.

 

여기서 환경은 Lexical Environment를 말한다!

 

그러니까 외부 환경은 외부의 Lexical Environment에 대한 참조가 된다!

 

즉, 현재와 관련 있는 외부에 있는 컨텍스트의 식별자 정보를 참조한다 보면 된다. 

 

 

현재 실행준인 문맥이 inner에 있다고 생각해보자. 

 

inner에는 environmentRecord / outerEnvironmentReference가 있다. 

 

inner의 outerEnvironment는 자기보다 밑에, 그러니까 자기보다 바깥에 있는 outer라고 하는 실행 컨텍스트를 참조한다.

 

무언가 chain처럼 연결되어 있는거 같지 않은가?

 

그렇다! outerEnvironment가 관여하는 것이 scope Chain이다!

 

Scope Chain 현상은 결국 outerEnvironment에 의해 만들어지는 거란다!

 

Scope란 무엇인지 우선 긁어온 블로그에서 공부하고 오시죠

 

https://medium.com/@yeon22/javascript-%EC%8A%A4%EC%BD%94%ED%94%84-scope-%EB%9E%80-bc761cba1023

 

(JavaScript) 스코프(Scope)란?

자바스크립트를 공부할 때 스코프(Scope)란 단어를 많이 접할 수 있는데요. 이 스코프란 무엇인지에 대해 알아보겠습니다.

medium.com

 

 단순하게 말해서 스코프는 변수의 유효 범위를 말한다.  외부로는 나갈 수 있는데  자기보다 더 안쪽으로는 못들어간다.

 

그러면 스코프 체인(Scope Chain)이란?

 

위 그림을 보면

 

inner 컨텍스트에서 선언한 변수는 environment에 의해서 접근이 가능하다. 

그리고 outerEnvironmentReference를 통해서 outer의 LexicalEnvironment정보에도 접근할 수 있다. 

 

한편, outer 컨텍스트의 입장에서는 outer내부에서 선언한 식별자들과  전역 공간에서 선언한 변수에도 접근이 가능하다!

 

하지만 inner에서 선언한 변수들은 반대로 outer에서 접근이 불가능하다. 

 

왜냐하면 outer에는 inner의 LexicalEnvironment에 대한 접근할 수 있는 수단이 없어서이다.(참조 수단이 없음! )

 

그래서 아니 ScopeChain이 머냐고 ㅡㅡ;; 까먹은게 아니다 조금만 기다려달라!

 

간략하게 순서를 정리하면

 

  1. inner에서 특정 변수를 찾는다. 
  2. 없으면 outerEnvironmentReference를 타고 outer의 LexicalEnvironmentd의 environmentRecord에서 변수를 찾음
  3. 해당되는게 없으면 outerEnvironmentReference를 타고 전역변수의 LexicalEnvironmentd의 environmentRecord에서 변수를 찾음

이것이 바로 스코프 체인이다!

 

가장 가까운 것부터 찾아서 가장 먼저 찾아지는 것만 접근이 가능하다! => 쉐도잉

 

이 그림을 보면 좀 더 이해가 갈 것이다. inner에서 a를 찾앗는데 없으면 outer로 가고, outer에도 없으면 전역으로 가서 찾는것이다. 만약 inner에 "var a = 1;"이 이미 선언되어 있으면 inner는 다른곳에서 찾지 않고 var a = 1를 바로 사용할 것이다. 다른 컨텍스트의 a에는 접근이 가능한가? 아니 ^^ 못한다! 

 

그러면 위를 바탕으로 다시 맨처음 실행 순서때 썻던 코드를 다시 읽어보겟다.

var a = 1;
function outer(){
    console.log(a);
    function inner(){
        console.log(a);
        var a = 3;
    }
    inner();
    console.log(a);
}

outer();

console.log(a);

 

  1. 전역 컨텍스트 정보 수집 : 변수 a / 함수 outer() 선언
  2. 변수  a에 1 할당
  3. outer함수 호출 => 함수 종료 대기 (1)
  4. outer함수 안에 컨텍스트 수집 : 함수 inner() 선언 
  5. console.log(a)실행 => a를 찾아보니 없어서 outerEnvironmentReference를 통해 전역 컨텍스트에 변수 a가 선언되어 있는지 확인하고 사용해서 씀 => 1 출력
  6. innter함수 호출 => 함수 종료 대기(2)
  7. inner 함수를 호출하니 다시 inner함수에 대한 실행 컨택스트가 다시 열림. 다시 변수 수집! 변수 a선언
  8. console.log(a)실행 => 현재 inner함수 안에서 a가 선언되기도 전에 불러서 undefined출력
  9. 그 다음에 a에 3 할당
  10. inner함수가 종료되면 inner 컨텍스트도 종료 =>inner context 의 call stack이 빠짐
  11. console.log(a)실행 => 1 출력
  12. outer함수 종료 

여기서 보다보면

 

아니? inner함수에 a 선언 됏는데 왜 console에서 undefined 야! 이거 블로그 잘못썻네 ㅎㅎ 

할수도 있지만...

 

여기 8번에서 undefined가 출력된 이유는 inner함수 안의 environmentRecord가 변수 a를 선언만 해 놓으니 이미 a는 안에 존재하므로 undefined 이어도 어쨋든 존재하기 때문에 scope chain을 통해 다른 곳의 변수를 찾지 않는다. 그래서 undefined가 나오는 것이다 !

 

그래서 outer함수에서 console.log(a)를 할 때는 정말로 선언이 되어 있지 않아서 scope chain을 통해 전역 컨텍스트의 a에 접근한 것이다!!

 

후... 정말 길엇다... 아무쪼록 공부하면서 javasciprt에 대해 좀 더 이해하는 시간이 되었다 뿌듯~

 

'programming language > javascript' 카테고리의 다른 글

Prototype이란?  (4) 2021.09.02
Closure란?  (0) 2021.09.01
Callback Fucntion 이란?  (0) 2021.09.01
This란?  (0) 2021.09.01
Primitive Type vs Reference Type  (5) 2021.08.29