컴퓨터 공학, 그리고 자바스크립트에서의 스코프의 의미 : "변수의 유효범위"
# 스코프 규칙 1
바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용 가능하다.
하지만 안쪽 스코프에서 선언한 변수는 바깥쪽 스코프에서 사용 불가능하다.
1. 예제로 알아보는 스코프(1)
let username = 'kimcoding';
if (username) {
let message = `Hello, ${username}!`; //username을 바깥 스코프에서 가져올 수 있으므로 정상적으로 출력.
console.log(message); // 'Hello, kimcoding'
}
console.log(message); // ReferenceError. message는 안쪽 스코프(중괄호 안쪽)에 선언되어있으므로, 바깥쪽에서 접근 불가능.
이처럼 변수에 접근할 수 있는 범위가 존재한다.
중괄호(블록) 안쪽에 변수가 선언되었는가, 바깥쪽에 선언되었는가가 중요하다. 이 범위를 스코프라고 부른다.
어디에 변수가 선언되었는지에 따라 그 변수에 접근할 수 있는 범위가 다르다.
let greeting = 'Hello';
function greetSomeone() {
let firstName = 'Josh';
return greeting + ' ' + firstName; //greeting변수는 바깥 스코프에 정의되어 있으므로, 함수 안쪽에서 사용할 수 있다.
}
console.log(greetSomeone()); // 'Hello Josh'
console.log(firstName); // ReferenceError. firstName변수는 안쪽스코프에 정의되어 있으므로 바깥쪽스코프에서 접근 불가능.
greeting변수가 바깥(바깥쪽 스코프)에 정의되어 있으므로, 함수 안쪽에서 사용할 수 있다.
하지만, firstName은 함수 안쪽(안쪽 스코프)에 정의되어 있으므로 함수 바깥쪽(바깥 스코프)에서는 접근 불가능하다.
즉, 범위가 중괄호(블록) 또는 함수에 의해 나누어지고, 그 범위를 스코프라고 부른다.
# 스코프 규칙 2
스코프는 중첩이 가능하다.
- 특별히 가장 바깥쪽의 스코프는 "전역 스코프(Global Scope)"라고 부르고, (여기서는 scope1이 Global scope) 전역 스코프에서 선언한 변수를 "전역 변수"라고 부른다.
- 전역 스코프가 아닌 스코프는 전부 "지역 스코프(Local scope)"라고 부르고, (여기서는 scope1을 제외한 나머지 scope들이 전부 지역 스코프) 지역 스코프에서 선언한 변수를 "지역 변수"라고 부른다.
# 스코프 규칙 3
지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.
[예제]
let name = '김코딩';
function showName() {
let name = '박해커';
console.log(name); // '박해커'
}
console.log(name); // '김코딩':전역변수로 선언된 name을 가져온 것. showName 함수 안의 name은 지역변수이므로 바깥쪽에서 안쪽은 접근 불가능.
showName(); // '박해커':전역변수명, 지역변수명이 동일하지만 지역변수가 전역변수보다 더 우선순위가 높다. 그래서 지역변수를 출력 -> 쉐도잉(Variable Shadowing) 현상
console.log(name); // '김코딩':전역변수 name출력. 지역변수 name은 안쪽 스코프이므로 바깥 스코프에서 접근 불가능.
** 쉐도잉(Variable Shadowing) : 동일한 변수명으로 인해 바깥쪽 변수가 안쪽 변수에 이해 가려지는 현상.
let name = '김코딩';
function showName() {
name = '박해커'; //위 문제와는 다르게 let키워드를 사용하지 않았다. 이는 전역에 선언된 name변수를 그대로 사용하겠다는 의미. 지역 스코프에서 새로 선언되지 않으면 같은 변수이다.
// **만약 여기서 var키워드를 사용해 var name이라고 선언하면, var은 함수스코프는 적용되므로 전역변수를 재할당하지않는다.
console.log(name); // '박해커'
}
console.log(name); // '김코딩':showName함수가 실행되기 전이므로 '김코딩'출력
showName(); // '박해커': showName함수가 실행되면서 전역 name변수에 값이 재할당됐다. 이제 전역변수 name값은 '김코딩' -> '박해커'.
console.log(name); // '박해커'
# 스코프의 종류
스코프의 종류는 2가지 존재한다.
1. 블록 스코프(block scope) : "중괄호"를 기준으로 범위 구분
(두번째 예제의 변수 i : 중괄호 안에서만 사용할 수 있다.)
2. 함수 스코프(function scope) : 함수로 둘러싼 범위.
function 키워드가 등장하는 함수 선언식 및 함수 표현식은 함수 스코프를 만든다.
**유의점 : 화살표 함수는 블록스코프로 취급된다. 함수 스코프가 아니다.
## 블록스코프의 규칙
- 블록 스코프 안에 선언된 변수는 범위를 벗어나는 즉시, 접근할 수 없다.
for (let i = 0; i < 5; i++){
console.log(i);//0, 1, 2, 3, 4 차례대로 출력
} //블록 스코프 안에서 정의된 i. 블록 범위를 벗어나면 접근 불가능.
console.log('final i:' i); // ReferenceError
for (var i = 0; i < 5; i++){
console.log(i);//0, 1, 2, 3, 4 차례대로 출력
} //
console.log('final i:' i); // final i: 5 출력
//블록을 벗어나도 변수 i에 접근 가능. 왜? --> var키워드는 블록 스코프를 무시한다.
- var 키워드는 블록 스코프를 무시하고, 함수 스코프만 따른다.
(그러나, 모든 블록 스코프를 무시하는건 아니다. 화살표 함수의 블록스코프는 무시하지 않는다.)
보통 코드를 작성할 때 블록은 들여쓰기가 적용되고, 그 구분이 시각적으로 분명하다.
따라서 많은 사람들은 블록스코프를 기준으로 코드를 작성하고 생각한다. 하지만 var 키워드는 이 규칙을 무시하므로 var보다는 let으로 변수선언을 권장한다.
[스코프 관련 문제 및 풀이]
https://lion284.tistory.com/118
**모든 그림 및 글의 출처는 '코드스테이츠'입니다.
'JavaScript' 카테고리의 다른 글
널 병합 연산자 ?? (Nullish coalescing operator) (1) | 2023.10.25 |
---|---|
표현식과 문 (0) | 2023.09.21 |
화살표 함수의 this (0) | 2023.09.15 |
자바스크립트 ES6모듈 내보내기/불러오기(export/import) (0) | 2023.08.16 |
함수 호출 방식에 의해 결정되는 this - 1. 함수 호출 (0) | 2023.07.05 |