전역 및 로컬 변수 범위

이 도움말에서는 범위 및 JavaScript에서 범위가 작동하는 방식을 알아봅니다.

범위는 변수에 액세스하고 사용하는 컨텍스트를 정의하는 JavaScript 및 기타 프로그래밍 언어의 기본 개념입니다. JavaScript를 계속 배우고 변수를 사용하여 더 많은 작업을 할수록 코드에 더 유용하고 적용 가능합니다.

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

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

범위란 무엇인가요?

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

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

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

이 도움말의 이후 섹션에서는 블록 및 어휘 범위를 설명합니다.

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

변수가 범위 내에서 액세스되면 JavaScript는 할당된 값을 반환하거나 그렇지 않으면 오류를 생성합니다.

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

  • 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!

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

로컬 범위 및 함수 범위

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

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

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

addNumbers(3, 4);

letconst 키워드를 사용하여 변수의 이름을 지정할 수 있습니다. 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 루프 외부로 유출되었으며 var 키워드가 블록 범위를 사용하지 않으므로 여전히 2 값을 유지하는 것을 확인할 수 있습니다. 이 문제는 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 코드를 구성하는 데 도움이 됩니다. 올바르게 사용하면 코드베이스에 효과적인 구조를 제공하고 코드 재사용에 도움이 됩니다. 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 범위 시각화 도구를 사용하여 직접 코드를 작성해 보세요. 데모는 코드에 색상을 사용하여 JavaScript 범위를 시각화합니다.

결론

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

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