8-1. 스코프란?

스코프(scope)는 변수, 함수, 클래스 등의 식별자가 유효한 범위를 말한다. 식별자는 선언한 위치에 따라 접근할 수 있는 유효 범위가 달라진다. 스코프는 대부분의 프로그래밍 언어에 존재하는 공통적인 개념이다. 하지만 자바스크립트 var 키워드의 스코프는 다른 언어의 스코프와 조금 다른 방식으로 동작하기 때문에, 우선 const 키워드로 스코프의 기본 개념에 대해 살펴보자.

const num1 = 1;

{
    const num2 = 2;
    console.log(num2); // 2
}

function scopeFunction1() {
    const num3 = 3;

    function scopeFunction2() {
        const num4 = 4;
    }
}

console.log(num1); // 1
console.log(num2); // Uncaught ReferenceError: num2 is not defined
console.log(num3); // Uncaught ReferenceError: num3 is not defined
console.log(num4); // Uncaught ReferenceError: num4 is not defined

식별자는 자신이 선언한 위치에서만 유효하기 때문에 블록 내부에서 선언한 식별자는 해당 블록 내부에서만 접근할 수 있다. num2, num3, num4는 블록 안에서 선언한 지역 변수이기 때문에 외부에서 접근했을 때 Uncaught ReferenceError가 발생하는 것이다.

8-2. var 키워드

자바스크립트에선 원래 변수를 선언할 때 var 키워드를 사용했지만, ES6 이후 let과 const 키워드가 추가되었다. var과 let, const 키워드는 스코프 동작 방식이 다르다. 이 키워드들에 대해 순서대로 알아보자.

8-2-1. 키워드 없이 선언과 할당 가능

var 키워드는 다른 프로그래밍 언어들의 변수 선언과는 다른 독특한 방식으로 동작하고, 여러 문제점을 가지고 있다. 가독성이 나쁘고 유지 보수가 어렵기 때문에 ES6에서 let과 const 키워드가 도입된 이후로는 잘 사용되지 않는다. 우선 다음 예제를 보자.

str = 'Hello World';

console.log(str); // 'Hello World'

다른 프로그래밍 언어에 익숙한 독자라면, 이 코드 이전에 str이라는 변수가 이미 선언되어 있고, 해당 코드는 str에 값을 재할당하는 것으로 생각하기 쉬울 것이다. 하지만 해당 코드는 변수를 선언함과 동시에 값을 할당한 것이다. var 키워드는 이렇게 키워드를 생략한 선언과 할당이 가능하다. 이런 방식은 해당 코드가 선언인지, 재할당인지 명확하지 않아 가독성을 떨어트릴 뿐만 아니라 치명적인 에러를 일으킬 수도 있다. 만약 홈페이지 회원의 이메일 주소를 수정해야 한다고 가정해 보자.

var memberMailAddress = '[email protected]';

memberMailaddress = '[email protected]'; // var 키워드 생략

console.log(memberMailAddress); // [email protected]
console.log(memberMailaddress); // [email protected]

개발자는 memberMailAddress라는 변수의 값을 수정해야 하지만, 실수로 대소문자를 헷갈려서 memberMailaddress라는 새로운 변수를 선언하고 말았다. 이렇게 되면 실제 회원의 이메일 주소는 수정되지 않아 이전 주소 그대로 남게 되는 것이다.

8-2-2. 중복 선언 가능

var 키워드의 또 다른 특징은 중복 선언이 가능하다는 것이다. 도서관 대출/반납 프로그램을 만든다고 생각해 보자.