본문 바로가기
Language/JavaScript

[JavaScript] Scope의 개념과 함수,블록 레벨 스코프

by 며루치꽃 2021. 1. 12.

Scope의 개념

 

Scoping: 프로그램의 변수를 구성하고 액세스하는 방법

Lexical Scoping: 코드의 함수 및 블록 배치에 의해 제어됩니다.

Scope: 특정 변수가 선언된 공간 또는 환경입니다. Scope에는 3가지 종류가 있습니다

  • 전역 스코프(Global scope)
  • 함수 레벨 스코프(Function-level scope)
  • 블록 레벨 스코프(Block-level scope)

 

대부분의 프로그래밍 언어는 블록 레벨 스코프(Block-level scope)를 따르지만 자바스크립트는 함수 레벨 스코프(Function-level scope)를 따릅니다.

 

  • 함수 레벨 스코프(Function-level scope)

함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없습니다. 즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수입니다. function scope는 locally scope이기 때문에 함수 선언 외부에서 접근할 수 없었습니다. 함수 선언, 함수실행 과 화살표 함수들은 모두 그들만의 scope를 가졌습니다. 함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다. 즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수입니다.

 

  • 블록 레벨 스코프(Block-level scope)

모든 코드 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없습니다. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수입니다.

 

var a = 1; // 전역 변수

console.log(a); // 1

{
  var a = 2; // 전역 변수
}

console.log(a); // 2

블록 레벨 스코프를 따르지 않는 var 키워드의 특성 상, 코드 블록 내의 변수 a는 전역 변수이다. 그런데 이미 전역 변수 a가 선언되어 있다. var 키워드를 사용하여 선언한 변수는 중복 선언이 허용되므로 위의 코드는 문법적으로 아무런 문제가 없다. 단, 코드 블록 내의 변수 a는 전역 변수이기 때문에 전역에서 선언된 전역 변수 a의 값 1을 새로운 값 2로 재할당하여 덮어쓴다.

 

전통적으로 scope를 만드는 것은 함수만 있었습니다. 그러나 , ES6에서 부터 block은 이제 범위를 만듭니다. block의 의미는 if 문의 블록이나 for 루프와 같이 중괄호 사이에 있는 모든 것을 의미합니다. 

 

블록 레벨 스코프(Block-level scope)

let a = 1; // 전역 변수

{
  let a = 2; // 지역 변수
  let b = 3; // 지역 변수
}

console.log(a); // 1
console.log(b); // ReferenceError: bar is not defined

let 키워드로 선언된 변수는 블록 레벨 스코프를 따릅니다. 위 예제에서 코드 블록 내에 선언된 변수 a는 블록 레벨 스코프를 갖는 지역 변수이다. 전역에서 선언된 변수 a와는 다른 별개의 변수이다. 또한 변수 b도 블록 레벨 스코프를 갖는 지역 변수이다. 따라서 전역에서는 변수 b를 참조할 수 없습니다.

 

함수들에서는 block 안에서 선언하였고 외부에서는 접근이 불가능하였습니다.

block scope에서는 오직 let, const 변수 만 생성된 블록으로 제한됩니다. 

var 를 쓰면 여전히 block scope 바깥에서 접근이 가능합니다. ES5 이전에는 Global scope와 function scope를 가지고 있었기 때문에 var로 선언하였습니다. 

ES6에서는 모든 함수는 block scope를 갖고, let과 const 변수를 쓸 때는 block에서만 선언하고 block에서만 접근이 가능합니다.


블록의 scope는 기본적으로 외부로 나갈 때는, 부모 Scope를 참조할 수 있고 내부는 참조할 수 없습니다.

위 예시에서의 주목해야할 부분은 바로 보라색 block scope입니다. 

decade 변수는 const로 선언하였기 때문에 block scope 입니다. millenial 변수는 var로 선언했기때문에 함수 scope입니다. 함수 scope이기에 부모 Scope를 참조하여 그림과 같이 나온 것을 알 수 있습니다. 

 

댓글