본문 바로가기
javascript

실행컨텍스트 - 자바스크립트야 왜 그렇게 동작하니?

by 윤-찬미 2020. 9. 25.

서론

자바스크립트를 입문 했을때 가장 어려웠던건 실행컨텍스트 부분이였어요.

가장 어려운 개념이자, 자바스크립트의 동장 원리를 알기 위해 꼭 짚어야 하는 부분 입니다.

나는 간단한 예제와 그림을 통해 실행컨텍스트에 대해 이해를 돕고자 합니다.

이 포스팅은 제로초님과 각종 구글링으로 얻은 것들을 정리 한 것입니다!

 

우선 대충 읽어봐요

컨텍스트의 4가지 원칙 

1)처음에 브라우저가 코드를 읽을 때 전역 컨텍스트를 하나 만들어요! 그리고 함수를 호출 할때마다 함수컨텍스트도 만들죠 ㅎㅎ

2)컨텍스트 생성 시 컨텍스트 안에 변수객체(arguments, variable), scope chain, this 가 생성이 된답니다

3)컨텍스트 생성 후 함수가 실행되는데, 사용되는 변수들은 변수 객체 안에서 값을 찾고, 없다면 스코프 체인을 따라 올라가며 찾습니다

4)함수 실행이 마무리되면 해당 컨텍스트는 사라집니다.(클로저 제외) 페이지가 종료되면 전역 컨텍스트가 사라집니다.

오늘 대표로 쓰일 예제

var name = 'zero'; // (1)변수 선언 (6)변수 대입
function wow(word) { // (2)변수 선언 (3)변수 대입
  console.log(word + ' ' + name); // (11)
}
function say () { // (4)변수 선언 (5)변수 대입
  var name = 'nero'; // (8)
  console.log(name); // (9)
  wow('hello'); // (10)
}
say(); // (7)

제로초님이 너무 좋은 예제를 만들어 놓으셨길래 한번 가져와 보았다 

 

전역 컨텍스트 생성

 

처음 브라우저가 코드를 쭉 읽어요!

처음에 모든 것을 포함하는 "전역 컨텍스트" 라는 것이 생긴 답니다!

 

어렵게 생각하지 말아요! 그냥 커다란 박스가 하나 생긴다고 생각합시다!그리고 정의 되어있는 변수객체들을 담아요!

이 아이는 최상단에 위치해 있어요!

한번 전체적으로 쓱! 훑으면서 변수객체를 저장해요!

name,wow,say 

scope chain은 전역변수객체 즉 자기 자신이 되겠죠! 최상단에 위치해있으니깐요!

this는 따로 정의해준 것이 없으니, 기본값인 window입니다!

 

쭉 읽으면서 전역컨텍스트가 생성이 되었는데, 마지막줄에 say() 하며 say함수를 실행시켰네요!

 

함수 컨텍스트 생성 - say

name 변수는 함수 내에서 다시 정의 했어요! console.log(name)했을때 자기 컨텍스트에 있는 변수객체인 name에있는 값을 가져온답니다!

그리고wow를 실행시켰어요!

어라.. 근데 say 컨텍스트 안에는 wow 함수가 없어요. 

이럴때 컨텍스트는 스코프체인을 따라 올라가 상위 컨텍스트 변수객체에서 찾는답니다!

올라 가다보니 전역 컨텍스트에 wow함수가 있군요!!

또 wow함수를 실행 시키고 함수 컨텍스트가 만들어 진답니다!

함수 컨텍스트 생성 - wow

짠 wow함수컨텍스트가 생겨났어요.!

인자값으로 hello를 받았고 console.log(word+''+name)

했는데, 어라.. name은 wow함수컨텍스트 변수객체에 존재 하지 않아요!

이럴때 또  스코프 체인을 따라따라 올라가  상위 컨텍스트 변수객체 중에 name이 있는지 찾아 본답니다!

 

전역 컨텍스트 변수객체에 name이 존재 하는 군요!

zero!

 

아까 say함수내에서의 name이랑은 다른 값을 참조하고 있는거랍니다! 다른 변수객체에 있는 값을 가져 온 것이니깐요 ㅎㅎ

 

스코프 체인이 어려운 개념이 아니에요 ㅎㅎ

그냥 나한테 없음 부모들을 찾아가는거에요! 그게 마치 체인처럼 얽혀있다고 해서 스코프 체인인 것일 뿐! 

 

호이스팅

var name = "dumbo";
say();
function say() {
	console.log(name);
}

자 위와 같은 코드에서 say가 작동할까요? 

호이스팅 현상을 컨텍스트로 설명을 해드릴게요!

위와 같이 함수 표현식이 아니라 선언식일 경우엔 함수가 통째로 끌어올라 갑니다!

브라우저가 이 코드를 읽을때 전역 컨텍스트 변수객체 안에 say함수가 바로 대입되기 때문에 say가 실행될 수 있는것입니다!

var name = "dumbo";
say();
var say = function() {
	console.log(name);
}

하지만 위와 같이 함수 표현식일 경우엔 실제 say 에 할당될 function 로직은 호출된 이후에 선언되므로, say 는 함수로 인식하지 않고 변수로 인식합니다! 

코드를 브라우저가 읽을때 전체적으로 싸악 훑어서 전역 컨텍스트를 만들고 위에서부터 차근차근 읽으며 코드를 실행 시키는데 위와 같은 say()에서는 say가 아직 함수가 아니라 변수이고 값이 할당되어있지 않기 때문에 에러가 뜬다는 말입니다!

 

함수 표현식과 선언식은 차이가 좀 있는데 이렇게 표현식은 호이스팅의 영향을 받지 않기 때문에 장점이라고 말하기도 합니다!

 

더 자세한내용은 아래 링크를 통해 확인해보세요!

https://joshua1988.github.io/web-development/javascript/function-expressions-vs-declarations/

 

함수 표현식 vs 함수 선언식

(기본) 자바스크립트 함수 표현식과 함수 선언식에는 어떠한 차이점이 있는지 알아봅니다.

joshua1988.github.io

 

클로저

전 사실 예전에 공부하면서 클로저 개념이 왜이렇게 어렵고 또 어려웠는지..

물론 아직도 모든게 어렵습니다.

function outter(){
    var title = 'coding everybody';  
    return function(){        
        alert(title);
    }
}
inner = outter();
inner();

클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미합니다!