티스토리 뷰

# 스코프(Scope)란?

JavaScript에서 변수, 객체, 함수가 접근할 수 있는 유효 범위이며 현재 실행되는 실행 문맥의 어휘적 환경(Lexical Environment)을 말합니다. 어휘적 환경은 어휘 중첩 구조(Logical nesting of Lexical Environment values)를 기반으로 특정 변수 및 함수에 식별자를 연결하는 사양입니다.

 

Scope는 전역 스코프와 지역 스코프가 있습니다.

또한 함수나 객체, 변수가 선언(function, function*, class, var, const, let)될 때 결정이 되며 이러한 특성을 Lexical Scope라고 합니다.

 


# 알아보기

전역 스코프

함수의 안이든 밖이든, 어느 위치에서나 접근할 수 있는 스코프를 말합니다.

ES5 문법의 유일한 변수 선언 키워드인 var는 함수 스코프를 가집니다. 함수 외부에 선언되면 전역 스코프, 내부에 선언되면 지역 스코프를 가집니다.

var global = 1;

function print () {
  console.log(global);
}

console.log(global); // 1
print(); // 1

print함수는 전역 스코프를 가지며 이 함수 내부에서 전역 스코프에 있는 global 변수에 접근이 가능합니다.

이 과정에서 스코프 체인(중첩된 어휘 구조의 상위 탐색)이 이루어집니다. 이에 관련된 설명은 여기서 확인할 수 있습니다.


for(var globalNumber=0; globalNumber < 1; globalNumber++) {
  var forValue = 1;
  console.log(forValue); // 1
}
console.log(globalNumber, forValue); // 1 1

for문은 함수가 아니기 때문에 내부에서 위 예시에서 선언된 변수들은 전부 전역 스코프입니다.

 

 

암묵적 전역 스코프

만약 선언 키워드가 없이 변수를 초기화하면 암묵적으로 전역 스코프가 됩니다.

function createGlobalVariable () {
  global = 1;
}
createGlobalVariable();

console.log(global); // 1

함수 내부에 선언된 변수지만 키워드가 없이 선언되었기 때문에 전역 스코프를 가집니다.

 

 

지역 스코프 (함수)

함수 내부의 스코프를 말하며 이 스코프에 선언된 변수를 지역 변수라고 합니다.

var value = 'global';

function print () {
  var value = 'local';
  console.log(value);
}
print(); // local
console.log(value); // global

print함수 내부에 선언된 value는 함수 스코프를 가지며 전역 스코프의 value변수와는 다른 값을 가지고 있습니다.


function print () {
  var value = 'local';
  console.log(value);
}
print (); // local
console.log(value); // error: Uncaught ReferenceError: value is not defined

함수 외부에서 지역 스코프에 있는 변수에 접근하려 하면 에러가 발생합니다.


물론 변수뿐만 아니라 함수 내부에 함수를 선언했을 때도 동일합니다.

function outerFunction () {
  console.log('This Function is hoisted!');


  function innerFunction () {
    console.log('innerFunction');
  }
  innerFunction(); // innerFunction
};

outerFunction(); // This Function is hoisted!
innerFunction(); // Uncaught ReferenceError: innerFunction is not defined

 outerFunction 내부에 선언된 innerFunction은 함수 스코프를 가지기 때문에 외부에서 호출하려 하면 에러가 발생합니다.

 

 

지역 스코프 (블록) (=중괄호, {})

ES6 문법이 도입되면서 새로 추가된 키워드가 있습니다. constlet이죠.

이 키워드들은 함수 스코프가 아닌 블록 스코프를 가집니다. 위 키워드를 가진 변수가 코드 블록(함수, if문, for문, while문, try/catch문 등) 내에 선언되면 해당 블록 외부에서는 접근할 수 없습니다. 물론 블록 외부에서 선언될 경우 전역 스코프를 가집니다.

{
  var varVariable = 1;
  console.log(varVariable); // 1
}

console.log(varVariable); // 1
function print () {
  {
    var varVariable = 1;
    console.log(varVariable); // 1
  }
  console.log(varVariable); // 1
}
print();

console.log(varVariable); // Uncaught ReferenceError: varVariable is not defined

위 두 개의 예시를 보면 var 키워드로 선언된 변수는 함수 스코프를 가지기 때문에 코드 블록과 상관없는 모습을 볼 수 있습니다.


그럼 constlet으로 선언된 예시를 보겠습니다. const는 Read Only(재할당이 불가능함)을 나타내는 키워드이며 let은 변수를 나타내는 키워드입니다.

{
  const constVariable = 1;
  let letVariable = 1;
  console.log(constVariable, letVariable); // 1 1
}
console.log(constVariable, letVariable); // Uncaught ReferenceError: varVariable is not defined

const, let키워드로 선언된 변수는 블록 스코프를 가지기 때문에 블록 외부에서 접근할 수 없습니다.

댓글