안녕하세요. 휘입니다. 오늘은 자바스크립트 스코프에 대해 정리해보려고 합니다. 자바스크립트에서는 변수나 상수, 아규먼트 등이 생성될 때 일종의 접근 범위인 스코프(scope)가 정해지는데요. 스코프에는 글로벌 스코프(global scope)와 로컬 스코프(local scope)가 존재하며, 자바스크립트는 렉시컬 스코프(lexical scope) 방식을 따릅니다. 과연, 어떤 의미일까요?
글로벌 스코프란?
먼저, 글로벌 스코프입니다. 다음 예시에서 myName
변수는 글로벌 스코프를 갖는 전역 변수(global variable)로 선언되었는데요. 글로벌 스코프는 함수 바깥에서도 이를 참조할 수 있게 합니다.
var myName = "Jeong"
function callingName(){
console.log(myName);
}
callingName(); // -> Jeong
위의 예시에서처럼, myName
변수는 callingName
함수 바깥에 있지만, 함수 내부에서 이를 호출할 수 있는 글로벌 스코프이며, 이러한 변수를 전역 변수라고 합니다.
로컬 스코프란?
로컬 스코프는 글로벌 스코프와 다르게 블록 또는 함수 내에서만 접근할 수 있습니다. 첫 번째 글로벌 스코프의 예시에서 myName
은 전역 변수로 선언되었지만, 두 번째 경우에서 myName
은 callingName
함수 내의 지역 변수(local variable)로 선언되었습니다. 따라서 해당 함수 내에서 myName
변수를 호출할 경우, Jeong
이 아닌 HeyJeong
이 출력됩니다.
let myName = "Jeong"
function callingName(){
let myName = "HeyJeong"
console.log(myName);
}
callingName(); // -> HeyJeong
주의해야 할 것은 두 번째 myName
로컬 변수가 글로벌 변수를 덮어쓰는 것이 아니며, 두 변수는 각각 다른 데이터로 존재한다는 것입니다. 다음 예에서 이를 확인할 수 있습니다.
let myName = "Jeong"
function callingName(){
let myName = "HeyJeong"
console.log(myName);
}
callingName(); // -> HeyJeong
console.log(myName); // -> Jeong
참고: 자바스크립트는 블록 {} 내에서 변수를 찾고, 해당 블록에 변수가 없을 경우 상위 블록(가장 가까운 지역 스코프 -> 상위 스코프 -> 글로벌 스코프)으로 이동합니다.
var와 let의 사용
이쯤에서 var
와 let
의 차이를 살펴보도록 하겠습니다.
var
키워드로 변수를 선언할 경우, 동일 스코프 내에서 변수를 재할당할 수 있습니다. 따라서 의도치 않게 값이 재할당될 수 있습니다.
function x () {
var x = 1;
var x = 2;
console.log(x); // 2
}
x();
반면, let
이나 const
로 변수를 선언하면, 동일 스코프 내에서는 변수를 재할당할 수 없습니다.
function y () {
let y = 1;
let y = 2;
console.log(y); // Uncaught SyntaxError: Identifier 'y' has already been declared
}
y();
이러한 변수 재할당 가능성 때문에 var
보다는 ES6 이훕터 적용된 let
또는 const
를 사용하는 것이 더 안전합니다.
렉시컬 스코프
마지막으로 렉시컬 스코프에 대해 살펴보도록 하겠습니다. 먼저, 용어를 이해해 보도록 하겠습니다. 렉시컬(lexical)의 사전적 의미는 '어휘의'인데요. 이렇게만 보면 어떤 의미인지 이해가 쉽지 않습니다. 렉시컬은 사전을 뜻하는 렉시콘(Lexicon)에서 파생되었습니다. 우리는 사전을 찾아볼 때, 문장의 문맥에 따라 단어의 의미를 찾아보는 것이 아니라, 사전에 정의된 의미를 따라 문장의 의미를 파악합니다. 이것이 바로 렉시컬의 의미입니다.
즉, 렉시컬 스코프란 함수가 호출되는 시점에 상위 스코프가 결정되는 것이 아니라, 함수가 선언되는 시점에 정의되는 것을 의미합니다. 전자의 경우를 동적 스코프(dynamic scope), 후자의 경우를 정적 스코프(static scope)라 하는데요. 이제, 렉시컬 스코프를 정적 스코프라 부르는 이유를 이해할 수 있습니다.
정리하자면, 자바스크립트는 렉시컬 스코프를 따르며 따라서 함수의 호출 위치가 아닌, 함수가 정의된 위치에서 상위 스코프가 결정됩니다.
그렇다면 다음 코드는 어떤 값을 출력할까요?
function rideBritishBoat() {
let boatName = "Queen's Dab";
function rideWelshBoat() {
boatName = "Welsh Royal Boat";
console.log(boatName)
}
rideWelshBoat();
}
rideBritishBoat();
더 읽어볼 자료:
참고 자료:
'개발 > JavaScript' 카테고리의 다른 글
[JavaScript] ④ 자바스크립트 객체란 무엇일까? (0) | 2020.06.20 |
---|---|
자바스크립트 do while 반복문 (0) | 2020.06.19 |
자바스크립트 조건문 if, else, else if 정리 (0) | 2020.06.18 |