개발 공부/JavaScript 공부

[JavaScript] 스코프 - scope, lexical scoping, hoisting

종범2 2020. 2. 16. 14:19

Scope

자바스크립트에서 scope란 변수에 접근할 수 있는 범위를 의미한다. 자바스크립트에서 두 가지 종류의 scope가 존재한다. Local scope와 gloabal scope이다. 함수 내에서 선언된 변수는 Local scope로 함수 내에서만 접근 가능하고, 함수 밖에서 선언된 변수는 global scope로 모든 곳에서 접근 가능하다. 대표적인 예시는 다음과 같다.

 

변수 a는 global scope로 선언하였고 변수 b는 func라는 함수 내에서 local scope로 선언하였다. a를 global scope로 선언하였기 때문에 func 함수 내에서 변수 a에 접근이 가능하다. 이때 다른 곳에서 변수 a와 변수 b에 접근이 가능할지 살펴보자.

 

결과는 다음과 같다. a는 gloabl scope이기 때문에 접근이 가능하지만 b는 접근이 불가능하다.

 

var로 선언한 변수의 Scope는 블록 단위가 아니라 함수 단위로 결정된다

위의 예제에서 b는 함수 내에서 선언하였기 때문에 함수 밖에서는 접근이 되지 않음을 확인하였다. 하지만 함수가 아니라 블록 내에서 선언하는 경우는 접근이 가능하다. 예제는 다음과 같다.

 

결과를 보면 변수 a는 local scope이고 변수 b는 global scope이다. 자바스크립트에서 블록 내에서 변수를 선언하면 global scope가 되기 때문이다.

 

let과 const로 선언한 변수의 scope는 블록 단위로 결정된다

블록 내에서 var로 선언한 변수는 global scope가 되지만 let과 const의 경우는 다르다. 블록 내에서 let과 const로 선언한 변수는 local scope가 된다. 예제는 다음과 같다.

 

 

Lexical Scoping

함수 내에서 선언된 변수의 scope는 함수를 호출할 때가 아니라 선언할 때 결정된다. 이를 lexcial scoping이라고 부른다.예제는 다음과 같다.

 

func함수는 global scope인 a변수를 출력하고 func2함수는 local scope인 a 변수를 정의하고 func함수를 호출한다. func2함수에서 func함수를 호출하면 global scope인 a를 출력하여 1을 출력한다. func함수를 global scope인 a 변수를 출력하도록 선언했기 때문이다. 만약 호출을 기준으로했다면 위의 코드와 다음의 코드가 같은 코드가 되어 2를 출력했을 것이다. 두 예제가 서로 다름을 인식해야한다.

 

 

변수 Hoisting

함수 내에서 변수 선언이 존재하면 현재 스코프의 가장 위에 모든 변수 선언을 이동시킨다. 이를 변수 Hoisting이라고 부른다. 변수 선언을 이동시키지 값의 대입까지 이동시키진 않는다. 예제는 다음과 같다.

 

func 함수 내에서 a를 선언하기 전에 출력했기 때문에 에러가 날거 같지만 hoisting으로 인해 a라는 변수가 출력전에 선언되어 undefined를 출력한다. 즉 hoisting으로 인해 이 코드는 다음의 코드와 같은 의미가 된다.

 

 

함수 Hoisting

변수 뿐만아니라 함수도 hoising 대상이다. 이때 함수에 변수를 대입하여 변수를 hoisting하는 경우와 함수 자체를 hoising하는 경우가 헷갈릴 수 있다. 우선 함수에 변수를 대입하는 경우에 대해 설명하겠다. 이 경우는 함수를 hoisting하는 경우가 아니다.

마찬가지로 func2라는 변수가 hoisting이 되어 에러없이 undefined를 출력한다. 하지만 다음의 경우에는 에러가 생긴다. 

 

func2라는 변수가 선언만 되어있지 함수를 대입하지 않았기 때문이다. 따라서 func2라는 함수를 실행할 수 없다. 하지만 다음의 예제에서는 에러가 뜨지 않는다. 이 경우는 함수를 hoisting하는 경우이다.

이 경우는 func2라는 변수에 함수를 대입한 경우가 아니라 func2라는 함수 자체를 선언한 경우이다. 함수도 hoisting 대상이므로 func2 함수를 호출하기 전에 선언이 되어있어 오류가 나지 않는다. 따라서 이 코드는 다음의 코드와 동일하다.

 

따라서 함수를 선언할 때 변수에 대입하여 선언하는 경우와 바로 함수를 선언하는 경우를 잘 구분해야한다.

 

참고자료

https://www.w3schools.com/js/js_scope.asp

 

JavaScript Scope

JavaScript Scope Scope determines the accessibility (visibility) of variables. JavaScript Function Scope In JavaScript there are two types of scope: Local scope Global scope JavaScript has function scope: Each function creates a new scope. Scope determines

www.w3schools.com

https://developer.mozilla.org/en-US/docs/Glossary/Scope

 

Scope

The current context of execution. The context in which values and expressions are "visible" or can be referenced. If a variable or other expression is not "in the current scope," then it is unavailable for use. Scopes can also be layered in a hierarchy, so

developer.mozilla.org

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

 

Hoisting

Hoisting is a term you will not find used in any normative specification prose prior to ECMAScript® 2015 Language Specification. Hoisting was thought up as a general way of thinking about how execution contexts (specifically the creation and execution phas

developer.mozilla.org