hoisting / Stack / Scope, Scopechain

pbs1014·2022년 4월 3일
0

자바스크립트는 실행컨텍스트를 생성하면서 코드에 관련한 실별자, 환경정보등을 수집한다.

따라서 코드가 실행되지 않았음에도 불구하고 자바스크립트 엔진은 환경에 속한 변수명들을 기억하고있으며 위에서 아래로내려가는 단방향 특징을 무시하고 저장된 변수를 멋대로 호출해 오는 경우가 생긴다.

이러한 특징을 호이스팅이라고 한다.

stack과 실행컨텍스트

호이스팅 전에 스택의 개념을 이해해야 한다.

Stack은 실행컨텍스트와 밀접한 연관이 있다. JavaScript 에선 이 입출력 구조가 Stack으로 구성되어 있기 때문이다.

스택의 간단한 예시이다 스택의 특징은 제일 마지막에 호출된 실행컨텍스트(ex.함수) 부터 실행이 되는 점이다.

다른 입출력 구조인 와는 상반되는 특징을 가지고 있다.


//(1)third() 실행 컨텍스트
function third(){
				 console.log("첫번째 실행 컨텍스트")
	//(2)second() 실행 컨텍스트
		function second(){
				consol.log("두번째 실행 컨텍스트")

		//(3)first() 실행 컨텍스트
			function firt(){
				console.log("세번째 실행 컨텍스트")
			}
			first()
		}
		second()
	}
third()

위 코드를 보면 이해를 도울 수 있다.
입력순서 : third -> second -> first 이며
출력순서 : first -> second -> third 가 된다.

Scope와 ScpoeChain

ScopeScopeChain 알아둬야할 중요한 요소이다.
Scope는 변수, 함수, 실별자.... 등등 각각의 유효범위를 나타내며
ScopeChain은 Scope 안에 필요한 값이 없다면 안=>밖으로 필요한것을 검색하나가는 것을 ScopeChain이라한다.

var a =1;  //전역공간 변수 
var outer = function () {
    var inner = function () {
        console.log(a)   ---------> undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1
}
outer()
console.log(a)   -----------> //결과 1

위 코드의 Scope를 봐보자
제일 큰 Scope는 전역변수 var a =1; 이 선언된 위 코드 전체이다.


그 다음 Scope는

var outer = function () {
    var inner = function () {
        console.log(a)   ---------> undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1
}

var outer = function () {~~~~} 전체가 scope가 되며


그 다음은 `var outer = function ()`함수 안쪽의
    var inner = function () {
        console.log(a)   ---------> undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1

가 된다.

ScopeChain으로 생각하면 가장 작은 Scope인 var inner = function()이 먼저 실행되며
안쪽에서 구할 수 있는 정보값이 없을 경우 순차적으로 그다음 Scope인 var outer = function () {~~~~}
만약 여기서도 구하지 못한다면 제일 큰 Scope였던 전역으로 검색을 나가게 되며
이 과정을 ScopeChain이라 생각해주면 된다.

이 과정은 스택의 특징을 지니고 있기에 스택 이후에 설명을 하였다.

hoisting

본론인 hoisting이다.
아래 코드를 통해 자세히 알아보도록 하자

var a =1;  //전역공간 변수 
var outer = function () {
    var inner = function () {
        console.log(a)   ---------> //결과 undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1
}
outer()
console.log(a)   -----------> //결과 1

위에서 말한 Stack/Scope의 개념을 적용시켜보면

제일 먼저 실행이 되는것은

var inner = function () {
        console.log(a)   ---------> //결과 undefined
        var a =3  //지역변수 
    }

이다.
var a = 3이 있음에도 결과가 undefined인 이유는 JavaScript의 단방.향(위->아래)로 코드를 읽는 특성때문이다.

var a = 3이 선언되기 전에 a의 console.log()를 먼저 받았으므로 undefined가 결과로 호출 된 것이다.

그 다음 실행은

var outer = function () {
    var inner = function () {
        console.log(a)   ---------> //결과 undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1
}

부분으로 outer함수 내에 a를 호출 할 값이 없기에 밖으로 탐색을 나가며 이과정에서 hoisting이 발생하여

이미 선언되어 입력값을 기억하고있는 변수var a =1을 가져와 console.log(a)에 1이 적힌것이다.

마지막 실행인 함수 전체 부분은
3.

var a =1;  //전역공간 변수 
var outer = function () {
    var inner = function () {
        console.log(a)   ---------> undefined
        var a =3  //지역변수 
    }
    inner()
    console.log(a)   ----------> //결과 1
}
outer()
console.log(a)   -----------> //결과 1

이미 해당 Scope가 함수 전체이므로
순서만 놓고 볼 경우
1. var a = 1;
2. var outer / outer()
3. console.log(a)
이기에 최초 선언된 var a=1;을 최하단의 console.log(a)가 바로 가져와 1이 출력된 것이다.

profile
프론트엔드 개발자 지망생 (react/next/js/ts)

0개의 댓글