스코프

안녕하세요😄

이번시간에는 자바스크립트의 스코프에 대해 다뤄보도록 하겠습니다.

스코프

스코프(Scope)는 직역하면 범위 라는 뜻으로, 자바스크립트에서는 우리가 변수 또는 함수를 생성할 때, 해당 변수 또는 함수가 갖게 되는 유효범위 를 뜻합니다.

자바스크립트의 스코프에는 여러 종류가 있습니다.

이 중에서, 전역 스코프와 지역 스코프에 대한 내용 먼저 살펴보겠습니다.

전역 스코프와 지역 스코프

전역 스코프는 영어로는 Global Scope로 전역에 선언되어있어, 어디서 든지 해당 변수에 접근 할 수 있는 범위를 뜻합니다.

반면, 지역 스코프는 Local Scope로, 말 그대로 해당 지역에서만 접근할 수 있는, 지역을 벗어난 곳에서는 접근할 수 없는 범위를 나타냅니다.

저번 시간에 배웠던 전역변수 혹은 외부변수는 아래에 보이는 코드의 sum 변수 처럼 어디서나 접근 가능하므로 전역 스코프를 갖고, 지역변수는 add함수 내부에 선언된 sum 변수와 같이 add함수의 내부에서만 접근 가능하기 때문에, 지역 스코프를 갖습니다.

코드 샌드박스에서 전역 스코프와 지역 스코프에 대해 더 자세하게 알아보도록 하겠습니다.

const num = 10; //전역 스코프

function print() {
    const num = 100; //지역 스코프
    console.log(`지역 스코프 ${num}`);
}

print();
console.log(`전역 스코프 ${num}`);

작성된 코드에서는 const 키워드를 사용해 10이라는 숫자가 저장된 num 변수를 외부에서 선언하고, 100이라는 숫자가 저장된 또 다른 num이라는 변수를 지역변수로 print라는 이름의 함수 내부에 작성했습니다.

코드를 실행시켜보면 오른쪽 콘솔탭에 적힌 결과와 같이,

지역 스코프 100
전역 스코프 10

이라는 값이 출력됩니다.

print 함수가 호출되어, 내부에 선언된 num 변수는 함수 내부에서만 접근 가능한 지역 스코프 이기 때문에 "지역 스코프 100" 이 출력되고,

함수의 외부에 있는 num 변수는 전역에서 접근 가능한 전역 스코프 이기 때문에 가장 마지막 줄에 있는 console.log() 를 통해 "전역 스코프 10" 이 출력되는 것을 확인 할 수 있습니다.

같은 지역에서만 접근 가능한 지역 스코프에는 함수 스코프와 블록 스코프 2가지 종류의 스코프가 있습니다.

이 2가지 스코프에 대해 자세하게 알아보겠습니다.

블록 스코프

먼저 블록 스코프에 대해 알아보겠습니다.

블록 스코프는 같은 블록에서만 접근 가능한 범위를 뜻합니다.

블록{} 내부에서 선언된 변수는 해당 블록에서만 접근 가능합니다.

블록 스코프를 나타내는 예시 코드를 작성해보겠습니다.

function print() {
    for (let i = 0; i < 10; i++) {
        console.log(`블록 스코프 : ${i}`); 
    }
    console.log(i); //ERROR
}

print();

작성된 코드를 보면, print 함수의 내부에 for문이라는 반복문을 이용해 i의 값을 작성한 것을 볼 수 있습니다.

반복문이란 특정 코드를 반복해서 실행해야할 때 사용하는 명령문입니다.

for문은 나중에 자세하게 다뤄볼 예정이지만, 간단하게 설명을 해보자면, for문의 괄호 안에는 이렇게, 초기화된 식, 조건식, 증감식이 존재합니다.

작성된 for문의 실행 순서를 보면, 0이라는 값이 할당된 i의 값이 조건식인 i<10 을 만족한다면, for문 안의 코드를 실행하고, 증감식을 통해 i의 값을 1 올려주게 됩니다.

이후 0이였던 i의 값이 1로 증가하고, 다시 조건문을 만족한다면, for문의 내부에 작성된 코드를 실행하고, 다시 증감식을 통해 i의 값을 1 증가시킵니다.

이러한 과정을 반복해서, i의 값이 10보다 작다 라는 조건식을 만족하지 않게 될 때 까지 해당 코드를 출력하는 명령문입니다.

코드를 실행시켜보면, for문의 안에 있는 콘솔은 오류 없이 잘 실행되어 i의 값이 0 부터 9까지 실행되지만, for문의 외부에 있는 콘솔은 출력되지 않고, "i is not defined" 라는 오류가 발생하게 됩니다.

우리가 배웠던 letconst 키워드는 블록 스코프로, for문의 괄호 안에 let으로 선언된 변수 i는 for문의 블록인 {}(중괄호) 안에서만 접근 가능한 블록 스코프에 해당하기 때문에, 해당 블록을 제외한 곳에서 접근가면 에러가 발생하게 됩니다.

let과 var

이전 강의에서, 우리는 자바스크립트에서는 letconst 라는 키워드로 변수를 생성한다고 배웠었는데요, 자바스크립트에는 var 라는 또 다른 키워드가 존재합니다.

let num1 = 10;
var num2 = 20;

num1 = 100;
num2 = 200;

console.log(num1); // 100
console.log(num2); // 200

let과 var 는 어떤 차이가 있는지 알아보기 위해 다음과 같이 각각의 키워드로 num1, num2 변수를 선언했습니다.

먼저, let으로 선언한 변수 num1에 숫자 10을 할당하고, 이후 100으로 값을 변경했습니다.

num1을 출력해보면 100 이라는 숫자가 잘 출력되는 것을 볼 수 있습니다.

마찬가지로 var 로 선언한 변수 num2도 숫자 20에서 숫자 200으로 중간에 값이 변경되었지만, 출력 결과 변경된 값인 200이 잘 출력 되는 것을 볼 수 있습니다.

이렇게 let과 var는 서로 유사하게 동작하는 키워드입니다.

하지만 var오래된 변수 선언 키워드 라고도 불리며, 잘 사용하지 않는 키워드 입니다.

그렇다면 let과 var는 어떤 차이점이 있는지, 그리고 왜 많은 사람들이 var 대신 let을 이용하여 변수를 선언하는지 살펴보도록하겠습니다.

1. 변수 선언 방식

let 과 var 를 사용해 변수를 선언한 다음, 동일한 이름의 변수를 다시 선언하는 코드를 작성해보겠습니다.

먼저 let 으로 변수를 생성해보면,

let num1 = 10;
let num1 = 100;

console.log(num1); //ERROR

코드 실행 결과 "이미 num1 이 선언되어있다" 라는 오류가 발생하는 것을 볼 수 있습니다.

그렇다면 var로 선언된 변수는 어떨지 확인해보겠습니다.

var num2 = 20;
var num2 = 200;

console.log(num2); //200

코드를 실행시키면, let처럼 에러가 발생하지 않고, 가장 위에 작성했던 20이라는 값이 아니라 마지막에 할당된 200 이라는 값이 출력되는 것을 볼 수 있습니다.

이렇게 var 키워드를 이용해 변수를 선언하면, 같은 이름의 변수를 여러번 다시 선언할 수 있고, 기존에 선언되었던 동일한 변수는 무시되는 것을 확인할 수 있습니다.

var로 선언된 변수가 더 유연하다고 생각하실 수 있지만, 코드량이 많은 자바스크립트 프로그램에서 var 로 변수를 선언한다면,

특정 변수가 이미 선언이 되어있는지 판단하기 어려울 뿐만 아니라, 어디서 어떻게 사용되고 있는지 파악이 힘들어지고 프로그램상의 오류를 발생시킬 수 있게된다는 단점이 있습니다.

2. 함수 스코프

let 과 var 의 또다른 차이점은 var은 함수 스코프 이며, let은 블록 스코프 라는 것입니다.

앞에서 작성했던 for문을, let을 var 로만 변경해 다시 작성해보도록하겠습니다.

function print() {
    for (var i = 0; i < 10; i++) {
        console.log(`블록 스코프 : ${i}`); 
    }
    console.log(i);
}

print();

for문안에 i라는 변수를 let으로 선언했을 때에는, 변수 i가 for문의 내부에서만 접근이 가능했기 때문에, for문의 외부에 있는 console.log(i) 가 실행되지 않고 에러를 발생시켰지만,

let을 var로 변경하니, 에러가 발생하지 않고, 10 이라는 숫자가 출력되었습니다.

동일한 코드이지만 결과가 다르게 출력되는 이유는, var 키워드는 해당 함수 안에서만 접근 가능한 범위를 갖는 함수 스코프 이기 때문에 print 함수의 내부에서 변수 i 에 접근하는 것이 가능해졌기 때문입니다.

이렇게 for문안에 선언된 변수가 var로 선언되게 되면, 해당 for문이 종료되더라도 같은 함수 내부에서는 계속 접근이 가능하기 때문에, 여러가지 오류를 발생시킬 수 있게 됩니다.

정리해보면, let은 같은 이름의 변수를 재선언하면 오류를 발생시키지만, var는 오류 없이 가장 마지막에 작성된 값으로 변수의 값이 변경되고, let은 블록 스코프, var는 함수 스코프라는 차이점이 있습니다.

이러한 var의 성질들은 자바스크립트를 이용한 프로그래밍에서 여러가지 오류들을 발생시킬 수 있다는 단점이 있기 때문에, 이번 강의에서는 var 를 사용하지 않고, let과 const만을 이용해 변수 및 함수들을 선언해보도록하겠습니다.

이번시간에는 자바스크립트의 스코프에 대해 알아보았습니다.

다음시간에는 자바스크립트의 호이스팅에 대해 배워보도록 하겠습니다.

감사합니다.

Last updated