전역 및 로컬 변수 범위

이 도움말에서는 범위 및 JavaScript에서 범위가 어떻게 작동하는지 알아봅니다.

범위는 자바스크립트 및 기타 프로그래밍 언어의 기본 개념으로, 변수에 액세스하고 변수가 사용되는 컨텍스트를 정의합니다. 계속해서 JavaScript를 학습하고 변수를 더 많이 다루면서 더 유용하고 코드에 적용할 수 있습니다.

범위는 다음과 같은 작업에 도움이 됩니다.

  • 메모리를 더 효율적으로 사용: 범위가 필요할 때만 변수를 로드하는 기능을 제공합니다. 변수가 범위를 벗어나면 현재 실행 중인 코드에서 사용할 수 있도록 설정할 필요가 없습니다.
  • 더 쉬운 버그 검색 및 수정: 변수를 로컬 범위로 격리하면 전역 변수와 달리 외부 범위의 코드는 로컬에서 범위가 지정된 변수를 조작할 수 없다는 것을 신뢰할 수 있으므로 코드의 버그 문제를 더 쉽게 해결할 수 있습니다.
  • 재사용 가능한 코드로 구성된 작은 블록 만들기: 예를 들어 범위 외부에 의존하지 않는 순수 함수를 작성할 수 있습니다. 최소한의 변경만으로 이러한 함수를 쉽게 다른 곳으로 옮길 수 있습니다.

범위란 무엇인가요?

변수의 범위는 코드 내에서 변수를 사용할 수 있는 위치를 결정합니다.

JavaScript는 다음과 같이 전역 또는 로컬 범위의 변수를 정의합니다.

  • 전역 범위가 있는 변수는 자바스크립트 코드 내 다른 모든 범위에서 사용할 수 있습니다.
  • 로컬 범위가 있는 변수는 특정 로컬 컨텍스트 내에서만 사용할 수 있으며 var, let, const와 같은 키워드로 생성됩니다. 함수 내에 var, let 또는 const 키워드를 사용하여 변수를 만드는 경우 해당 변수에 로컬 범위가 포함됩니다.

이 도움말의 뒷부분에서는 블록과 어휘 범위를 설명합니다.

  • 블록 범위 변수는 블록 구문이 정의된 중괄호의 위치에 따라 결정되는 대로 블록에 로컬로 사용할 수 있습니다. let 또는 const 키워드로 선언된 변수만 블록 범위를 갖습니다.
  • 어휘 범위는 소스 코드에서 변수가 선언된 위치를 사용하여 변수를 사용할 수 있는 위치를 결정합니다. 클로저를 사용하여 포함된 함수에 어휘적 환경이라고 하는 외부 범위에서 참조되는 변수에 대한 액세스 권한을 부여합니다.

범위 내에서 변수에 액세스하면 자바스크립트가 할당된 값을 반환하거나 그 외의 경우 오류가 발생합니다.

변수를 선언하는 방법은 다음과 같습니다.

  • var, const 또는 let 키워드를 사용하여 로컬 또는 전역 범위 변수를 선언합니다.
  • const 또는 let 키워드를 사용하여 블록 범위 변수를 선언합니다.

함수에서 var 변수를 선언하면 선언을 통해 가장 가까운 바깥쪽 함수에서 변수를 사용할 수 있습니다. var 키워드를 사용하여 블록 범위가 있는 변수를 선언할 수 없습니다.

범위 예시

이 예에서는 전역 범위를 보여줍니다. greeting 변수가 함수 또는 블록 외부에서 선언되어 값을 현재 문서의 모든 코드에서 사용할 수 있기 때문입니다.

const greeting = 'hello';
console.log(greeting); // 'hello'

전역 범위 예시에서는 greeting 변수에 hello 값이 할당됩니다.

이 예에서는 함수 내에서 let 키워드를 사용하여 greeting 변수를 선언하므로 로컬 범위를 보여줍니다. greeting 변수는 로컬에서 범위가 지정된 변수이며 함수 외부에서는 사용할 수 없습니다.

function greet() {
  let greeting = 'Hello World!';
  console.log(greeting);
}

이 예에서는 블록 범위를 보여줍니다. 중괄호 안에서만 변수에 액세스할 수 있도록 블록 내에 greeting 변수를 선언하기 때문입니다.

if (true) {
   const greeting = 'hello';
}

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

console.log 함수가 greeting 변수의 값을 출력하려고 하면 JavaScript가 예상 hello 메시지 대신 ReferenceError 오류 메시지를 반환합니다. 왜냐하면

오류가 반환되는 이유는 greeting 변수에 블록 범위가 있고 가장 가까운 블록이 if 조건문의 일부이기 때문입니다. 블록 외부에서 선언하는 letconst 변수에는 액세스할 수 없습니다. 따라서 블록 범위를 지정하는 중괄호 안의 greeting 변수에만 액세스할 수 있습니다.

이 예에서는 console.log(message) 메서드를 중괄호 안으로 이동하기 때문에 오류를 수정합니다. 업데이트된 코드는 블록 내부의 console.log(message) 메서드를 재배치합니다.

if (true) {
   const greeting = 'hello';
   console.log(greeting);
}

범위 유형

전역 범위

프로그램의 어디서나 전역 범위가 있는 변수에 액세스할 수 있습니다.

두 개의 JavaScript 파일 file-1.jsfile-2.js를 가져오는 HTML 파일이 있다고 가정해 보겠습니다.

<script src="file-1.js"></script>
<script src="file-2.js"></script>

이 예에서 globalMessage 변수는 전역 범위를 가지며 함수 외부에 작성됩니다. 실행 및 실행 중에 JavaScript 프로그램의 어디에서나 globalMessage 변수 값에 액세스할 수 있습니다.

다음 코드 스니펫에서 file-1.jsfile-2.js 파일의 콘텐츠를 확인할 수 있습니다. 두 파일에서 globalMessage 변수를 사용할 수 있습니다.

// file-1.js
function hello() {
    var localMessage = 'Hello!';
}

var globalMessage = 'Hey there!';

// file-2.js
console.log(localMessage); // localMessage is not defined
console.log(globalMessage); // Hey there!

이 도움말에서 자세히 다루지 않는 다른 유형의 범위가 있습니다. 자바스크립트 모듈 내에서 함수나 블록 외부에 변수를 만들면 전역 범위가 아니라 모듈 범위를 갖게 됩니다. 모듈 범위가 있는 변수는 현재 모듈 내의 어디서나 사용할 수 있지만 다른 파일이나 모듈에서는 사용할 수 없습니다. 모듈 범위 변수를 다른 파일에서 사용하려면 변수가 생성된 모듈에서 내보낸 후에 변수에 액세스해야 하는 모듈에서 import야 합니다.

로컬 범위 및 함수 범위

var, let 또는 const 키워드를 사용하여 JavaScript 함수에서 변수를 만들 때 변수는 함수에 로컬이므로 함수 내에서만 액세스할 수 있습니다. 로컬 변수는 함수가 시작될 때 생성되고 함수 실행이 완료되면 효과적으로 삭제됩니다.

이 예에서는 addNumbers() 함수에서 total 변수를 선언합니다. addNumbers() 함수 내에서만 a, b,, total 변수에 액세스할 수 있습니다.

function addNumbers(a, b) {
    const total = a + b;
}

addNumbers(3, 4);

let 키워드와 const 키워드를 사용하여 변수 이름을 지정할 수 있습니다. let 키워드를 사용하면 JavaScript가 변수를 업데이트할 수 있습니다. 그러나 const 키워드를 사용하면 변수가 일정하게 유지됩니다.

var variable1 = 'Declared with var';
var variable1 = 'Redeclared with var';
variable1; // Redeclared with var

let variable2 = 'Declared with let. Cannot be redeclared.';
variable2 = 'let cannot be redeclared, but can be updated';
variable2; // let cannot be redeclared, but can be updated

const variable3 = 'Declared with const. Cannot be redeclared or updated';
variable3; // Declared with const. Cannot be redeclared or updated

범위 차단

블록은 단일 문 또는 문 집합을 함께 그룹화하는 데 사용됩니다. const 또는 let 키워드를 사용하여 블록 범위 로컬 변수를 선언할 수 있습니다. var 키워드를 사용하여 블록 범위가 있는 변수를 선언할 수 없습니다.

예를 들어 이 블록에서 name 변수의 범위와 "Elizabeth" 값은 중괄호 안에 포함되어 있습니다. 블록 범위 내의 변수는 블록 외부에서 사용할 수 없습니다.

{
    const name = "Elizabeth";
}

if, for, while 문 내에서 블록 범위 변수를 사용할 수 있습니다.

이 코드 스니펫 내의 두 for 루프에 유의하세요. 하나의 for 루프가 var 키워드를 사용하여 이니셜라이저 변수를 선언합니다. 이 변수는 0, 1, 2의 숫자를 통해 증가합니다. 다른 for 루프는 let 키워드를 사용하여 이니셜라이저 변수를 선언합니다.

for (var i = 0; i < 2; i++) {
    // ...
}

console.log(i); // 2

for (let j = 0; j < 2; j++) {
    // ...
}

console.log(j); // The j variable isn't defined.

이전 코드 예에서 첫 번째 for 루프의 i 변수가 for 루프 외부로 유출되었으며 여전히 2 값을 유지합니다. var 키워드가 블록 범위를 사용하지 않기 때문입니다. 이 문제는 let 키워드로 선언된 j 변수가 for 루프의 블록으로 범위가 지정되고 for 루프가 완료된 후 존재하지 않는 두 번째 for 루프에서 해결됩니다.

다른 범위에서 변수 이름 재사용

다른 범위의 다른 곳에서 동일한 변수 이름을 재사용하더라도 범위는 함수 내에서 변수를 분리할 수 있습니다.

다음 예에서는 범위를 사용하여 다양한 함수에서 동일한 변수 이름을 재사용할 수 있는 방법을 보여줍니다.

function listOne() {
    let listItems = 10;
    console.log(listItems); // 10
}

function listTwo() {
   let listItems = 20;
   console.log(listItems); // 20
}

listOne();
listTwo();

listOne()listTwo() 함수의 listItems 변수에는 예상 값이 할당되므로 서로 충돌하지 않습니다.

클로저 및 어휘 범위

클로저는 내부 함수가 외부 함수 범위(어휘 환경이라고도 함)에 액세스할 수 있는 포함된 함수를 의미합니다. 따라서 JavaScript에서는 클로저를 사용하여 함수가 외부 어휘 환경을 참조할 수 있도록 합니다. 그러면 함수 내부의 코드가 함수 외부에서 선언된 변수를 참조할 수 있습니다. 실제로 함수가 특정 함수에 의해 호출되고, 그다음에 다른 함수가 호출되도록 외부 어휘 환경에 대한 참조 체인을 코딩할 수 있습니다.

이 예시에서 코드는 outer() 함수가 호출될 때 생성되는 어휘 환경으로 클로저를 형성합니다. 이 함수는 hello 변수에서 닫힙니다. 따라서 hello 변수는 setTimeout 콜백 함수 내에서 사용됩니다.

function outer() {
    const hello = 'world';

    setTimeout(function () {
        console.log('Within the closure!', hello)
    }, 100);
}

outer();

어휘 범위를 사용하면 런타임이 아닌 소스 코드를 컴파일하는 중에 범위가 결정됩니다. 어휘 환경에 관한 자세한 내용은 어휘 범위 지정 및 클로저를 참고하세요.

모듈

JavaScript 모듈은 JavaScript 코드를 구성하는 데 도움이 됩니다. 적절히 사용하면 코드베이스에 효과적인 구조를 제공하고 코드를 재사용하는 데 도움이 됩니다. 전역 변수를 사용하여 여러 파일에서 변수를 공유하는 대신 자바스크립트 모듈은 변수를 내보내고 import 기법을 제공합니다.

// hello.js file
function hello() {
  return 'Hello world!';
}

export { hello };

// app.js file
import { hello } from './hello.js';

console.log(hello()); // Hello world!

범위 시각화 도구 데모

범위는 모든 JavaScript 개발자가 이해해야 하는 기본 개념입니다. 범위 시스템을 더 잘 이해하려면 JS Scope Visualizer를 사용하여 직접 코드를 작성해 보세요. 데모에서는 JavaScript 범위를 시각화하는 데 도움이 되도록 코드에 색상을 사용합니다.

결론

이 도움말에서는 다양한 유형의 범위를 소개합니다. JavaScript 범위는 웹 개발의 고급 개념 중 하나이므로 이 콘텐츠를 읽고 시간을 들여 이 주제를 이해했다면 유용합니다.

범위가 사용자 대상 기능이 아닙니다. 이는 코드를 작성하는 웹 개발자에게만 영향을 미치지만 범위의 작동 방식을 알면 버그 발생 시 수정하는 데 도움이 될 수 있습니다.