Blog

Scope

개요

C, C++, Java, JavaScript 와 같이 대부분의 프로그램 언어들은 Lexical Scope ( 또는 Static Scope ) 를 사용하고 있다. Lexical Scope 의 반대 방식은 Dynamic Scope 가 있으며 Perl, Bash Shell 등이 사용한다.

시작하기 전에

아래의 코드를 실행하면 결과가 어떻게 출력될 지 생각해보자.
var age = 10; function echo() { console.log(age); } function wrap() { var age = 30; console.log(age); echo(); } wrap();
JavaScript
복사

Lexical Scope

Lexical Scope: use environment where function is defined. Dynamic Scope: use environment where function is called.
Lexical Scope는 변수나 함수가 정의된 곳에 따라 상위 스코프를 결정한다.
이 말을 조금 더 쉽게 풀어서 설명하면, 함수가 처음 선언된 순간 함수 내부의 변수는 스코프를 기준으로 가장 가까운 곳에 있는 변수를 참조하게 된다.
위의 코드를 예로 들어서 설명하면 echo 함수 안에 age 변수는 선언 시 가장 가까운 곳에 있는 전역 변수 age를 참조한다.
wrap 함수 안에서 age 변수를 선언해도 echo 함수는 전역 변수인 age를 바라보고 있기 때문에 전역 변수 값인 10 이 출력된다.
위의 코드의 결과는 아래와 같다.
30 10
JavaScript
복사

Function Scope

함수 내부에서 선언한 변수는 함수 내에서 계속 유효하며, 함수 외부에서는 참조할 수 없다.
function echo() { var age = 10; console.log(age); if (true) { var age = 20; console.log(age); } console.log(age); } echo(); console.log(age); // ReferenceError: age is not defined
JavaScript
복사
// 결과 값 10 20 20
JavaScript
복사

Block Scope

코드 블록 ( {} ) 내에0서 선언된 변수는 해당 블록에서만 유효하며, 외부 블록에서 참조할 수 없다.
function echo() { let age = 10; console.log(age); if (true) { let age = 20; console.log(age); } console.log(age); } echo();
JavaScript
복사
// 결과 값 10 20 10
JavaScript
복사

var vs let

ES6 에서 let, const keyword 가 추가되었다. var , let 은 변수를 선언하는 keyword 이지만, 많은 부분에서 차이가 발생한다.
var
Function Scope
Hositing
중복 선언 가능
function echo() { var age = 10; console.log(age); var age = 20; console.log(age); } echo();
JavaScript
복사
let
Blcok Scope
No Hoisting
중복 선언 불가능
function echo() { let age = 10; console.log(age); let age = 20; // SyntaxError: Identifier 'age' has already been declared console.log(age); } echo();
JavaScript
복사

참고