본문 바로가기

JavaScript

스코프 의미, 규칙 및 종류

컴퓨터 공학, 그리고 자바스크립트에서의 스코프의 의미 : "변수의 유효범위"

 

 

# 스코프 규칙 1

바깥쪽 스코프에서 선언한 변수는 안쪽 스코프에서 사용 가능하다.

하지만 안쪽 스코프에서 선언한 변수는 바깥쪽 스코프에서 사용 불가능하다.

 

 

1. 예제로 알아보는 스코프(1)

let username = 'kimcoding';
if (username) {
  let message = `Hello, ${username}!`; //username을 바깥 스코프에서 가져올 수 있으므로 정상적으로 출력.
  console.log(message); // 'Hello, kimcoding'
}

console.log(message); // ReferenceError. message는 안쪽 스코프(중괄호 안쪽)에 선언되어있으므로, 바깥쪽에서 접근 불가능.

바깥스코프에서 선언한 username변수를 안쪽 스코프에 가지고옴.
안쪽스코프에서 선언한 변수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

 

스코프 checkpoint 문제

스코프에 대해서 공부하였고, 제대로 이해했는지 확인하기 위해 checkpoint 문제를 풀어보았다. //Q.1 let x = 30; function get () { return x; //전역변수 x에서 가져온다. 함수 스코프 내에서 x를 별도로 선언.

lion284.tistory.com

 

**모든 그림 및 글의 출처는 '코드스테이츠'입니다.