스코프란?

스코프는 유효범위라는 의미 그대로 변수가 어느 범위까지 참조되는지를 뜻한다.

자바스크립트에서 스코프가 어떻게 동작하는지 정리해보자 😃

함수 레벨 스코프와 블록 레벨 스코프

자바스크립트에서는 2가지 레벨의 스코프가 있다.

그것이 바로 함수 레벨 스코프와 블록 레벨 스코프인데 이름 그대로 함수 레벨 스코프는 1개의 함수 안에서 까지만 유효범위를 갖는것을 의미하고 블록 레벨 스코프는 1개의 블록 내에서 까지만 유효한 범위를 갖는것을 의미한다.

블록은 중괄호 ({...}) 를 의미한다.

반복문, 조건문, 함수, 코드블록 등 중괄호를 사용하는 모든것들이 블록이다.

정리해보자면!

  • 함수 레벨 스코프 : 오직 함수의 내부의 유효한 범위를 갖는것

  • 블록 레벨 스코프 : 반복문, 조거문, 함수 등 블록 ({...}) 내부의 유효한 범위를 갖는것

함수도 블록이기 때문에 블록 레벨 스코프가 함수 레벨 스코프를 포함할수 있을텐데 왜 굳이 이렇게 나뉘었냐면 뒤에 설명할 변수의 선언을 var 로 했냐 let, const로 했냐에 따라 나뉘고 이 차이가 중요하기 때문이다.

모듈 레벨 스코프가 있다고?

자바스크립트에서 script를 모듈로 작성하면, 즉 여러개의 파일로 작성하면 각각 파일(모듈로써의 의미)별로 스코프를 갖는다.

각각의 파일들이 공유하는 전역공간이 있는게 아닌 자신만의 전역공간을 갖기 때문에 import를 하지 않는한 스코프를 공유할 수 없다.

<!DOCTYPE html>
<html>
  <head>
    <title>Document</title>
  </head>
  <body>
    <script type="module">
      const a = 1;
    </script>

    <script type="module">
      alert(a);
    </script>
  </body>
</html>

위와 같이 2개의 모듈을 만들고 첫번째 모듈에서 변수 a를 선언하고 두번째 모듈에서 변수 a를 사용하려고 하면 브라우저에서 아래와 같은 에러를 만날것이다.

Uncaught ReferenceError: a is not defined
    at index.html:12

전역 스코프와 지역 스코프

지역은 블록 내부를 의미한다. 지역 스코프이면 블록 내부에서 까지만 유효한 범위를 의미한다.

전역 자바스크립트 파일 가장 외부(최상단부)를 의미한다.

전역이 지역을 포함하고 있다.

const globalValue = 111;

{
  const localValue = 222;
  console.log(globalValue); // 111
  console.log(localValue); // 222
}

console.log(globalValue); // 111
console.log(localValue); // ReferenceError: localValue is not defined

전역에 선언한 변수는 지역 내부를 포함한 전역 어디에서든 참조가 가능하다.

하지만 지역에서 선언한 변수는 지역 스코프를 갖기 때문에 해당 지역 내부에서만 참조가 가능하다.

var vs let , const

  • var 는 함수 레벨 스코프이다.

  • let , const 는 블록 레벨 스코프이다.

예제를 한번 보자.

{
  var a = 111;
  let b = 222;
}

console.log(a); // 111
console.log(b); // ReferenceError: b is not defined

함수 레벨 스코프인 var 로 선언한 변수 a 는 블록 내부에 선언을 해도 블록의 영향을 받지않고 전역에서 참조가 가능하다.

하지만 블록 레벨 스코프인 let 으로 선언한 변수 b 는 블록 내부에 선언했다면 외부에서 참조가 불가능하다.

참고로 함수는 블록레벨이자 함수레벨이고 블록은 딱 블록레벨만을 갖는다.

🤔 전역객체에서 var 와 let

  • var 키워드로 선언된 변수를 전역 변수로 사용하면 전역 객체의 프로퍼티가 된다.
  • let 키워드로 선언된 변수를 전역 변수로 사용하는 경우, let 전역 변수는 전역 객체의 프로퍼티가 아니다. let 전역 변수는 보이지 않는 개념적인 블록 내에 존재하게 된다.

var, let, const의 선언 방식 차이

var : 선언 및 초기화 ➡️ 할당
let, const : 선언 ➡️ TDZ ➡️ 초기화 ➡️ 할당

profile
console.log(noah(🍕 , 🍺)); // true

0개의 댓글