본문 바로가기
Programming/Javascript

[JavaScript] 변수 선언 var 대신 let, const를 사용해보자

by 주리니e 2022. 10. 31.
728x90

[JavaScript] 변수 선언 var 대신 let, const를 사용해보자

 

 

ES5까지 변수를 선언할 수 있는 방법은 var 키워드를 사용하는 것이었다. 이는 다른 언어와는 다른 특징으로 주의를 기울이지 않으면 심각한 문제를 일으킨다. ES6부터는 let과 const 변수 키워드를 도입하였으며 var 키워드를 대체하여 사용할 수 있다. 각 변수 키워드별 사용방법 및 특징을 알아보고 앞으로는 let과 const를 어떤 상황에서 사용할지 알아보자.

  • var 키워드

var 키워드를 선언하면 재선언재할당이 가능하다. 재할당은 문제가 되지 않지만 재선언 시 오류가 발생하지 않는다면 해당 변수명을 중복으로 선언하여 의도하지 않은 실수를 초래할 수 있다.

<script>
    var email = 'jiurinie@gmail.com';
    var email = 'jiurinie2@gmail.com'; // 재선언
    
    email = 'jiurinie3@gmail.com'; // 재할당
    console.log(email);
</script>


아래와 같이 var 키워드를 생략하여 사용할 수 있다. 이는 무분별한 전역변수를 생성할 가능성이 높다. ES5에서 추가된 'use strict' 키워드를 최상단에 선언하여 방지할 수 있다.

<script>
    email = 'jiurinie@gmail.com'; // var 키워드 생략
    console.log(email);
</script>
<script>
    'use strict'

    email = 'jiurinie@gmail.com';
    console.log(email); // Uncaught ReferenceError: email is not defined
</script>


함수 안에서 생성된 var 키워드의 변수는 함수레벨(function) 안에서만 사용할 수 있다. 함수 외부에서 사용하려면 오류가 발생한다. 허나 블록레벨({} 중괄호 사용)의 범위(Scope)를 사용하지 않으므로 아래와 같이 for문 안에서 선언된 변수를 for문 밖에서 사용할 수 있다. 이는 의도하지 않게 변수의 값을 변경시킬 수 있고 복잡성을 증가시킨다. 따라서 변수의 스코프는 좁을수록 좋다.

<script>
    function func() {
        for (var i = 0;  i < 10; i++){
            var email =  'jiurinie@gmail.com';
        }
        console.log(email); // for 문안에 생성된 변수를 밖에서 사용
    }
    // console.log(email); ReferenceError : email is not defined

    func();
</script>

 

  • let과 const 키워드

위에 언급된 var 키워드의 문제점을 해결하여 사용할 수 있다. 변수의 재생성이 불가능하다. 재생성 시 변수가 이미 선언되어 있다고 오류를 발생시킨다. 또 블록레벨({} 중괄호 사용) 범위(Scope)를 지원함으로 if, for, while, {} 등 내부에서 사용된 변수를 외부에서 사용할 수 없다. 

<script>
        // 변수 재생성
        let name = 'jiurinie';
        // let name = 'jiurinie1'; Uncaught SyntaxError: Identifier 'name' has already been declared

        const email = 'jiurinie@gmail.com';
        // const email = 'jiurinie1@gmail.com'; Uncaught SyntaxError: Identifier 'email' has already been declared
 </script>
<script>
    function func() {
        if (true) {                
            let email =  'jiurinie@gmail.com';
            const age = 20;
        }
        console.log(email); // Uncaught ReferenceError: email is not defined
        console.log(age); // Uncaught ReferenceError: age is not defined
    }
    func();
</script>

 

  • let과 const 키워드의 차이

let은 재할당이 자유로우나 const는 재할당이 금지된다. const는 상수를 사용하기 위해서 선언하며 반드시 선언과 동시에 할당이 이루어져야 하며 수정이 불가능하다. 그래서 값이 변경되지 않는 변수를 선언할 때는 const 키워드를 사용하면 된다.

<script>
    let name;
    name = 'jiurinie';
    console.log(name);

    // const age; Uncaught SyntaxError: Missing initializer in const declaration 
    const age = 10;
    // age = 15; Uncaught TypeError: Assignment to constant variable.
    console.log(age);
</script>


추가적으로 const로 선언된 변수는 상수이므로 변경이 불가능하지만 object로 선언된 const 변수의 내부 값은 아래와 같이 변경이 가능하다.

<script>
    const jiurinie = {email : 'jiurinie@gmail.com'};
    // jiurinie = 'jiurinie@gmail.com'; Uncaught TypeError: Assignment to constant variable.

    jiurinie.email = 'jiurinie@email.com';
    console.log(jiurinie);
</script>


object로 선언된 const 변수의 내부 값을 변경할 수 없도록 하려면 Object.freeze 라는 메소드를 사용하여 불가능하도록 바꿀 수 있다. 아래코드는 내부 값을 변경하였지만 console로 확인하였을 때 변경되지 않는 값을 출력한다. 만약 이때 오류를 발생시키고 싶다면 최상단에 'use  strict' 를 선언하여 오류를 강제적으로 발생시킬 수 있다.

<script>
    const jiurinie = {email : 'jiurinie@gmail.com'};
    Object.freeze(jiurinie);
    jiurinie.email = 'jiurinie@email.com';
    console.log(jiurinie);
</script>

 

  •  javascript 호이스팅 현상

번외로 알아두면 좋을 호이스팅 현상에 대해서 설명한다. javascript에서는 변수 선언 시(변수뿐만 아니라 모든 선언 :var, let, const, function, function*, class) 호이스팅 현상이 일어난다.  이는 선언된 변수를 분리하여 해당 변수의 선언 범위(Scope) 안의 최상단에 변수를 선언한 후 아래에서 값만 할당시킨다.

 <script>   
   console.log(email);
   var email = 'jiurinie@gmail.com';
   console.log(email);
</script>

위 코드를 아래코드와 같이 내부적으로 변환하여 값을 출력하게 된다.

 <script>
   var email;
   
   console.log(email);
   email = 'jiurinie@gmail.com';
   console.log(email);
</script>

var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어져 undefined를 출력하지만 let 키워드로 선언된 변수는 선언단계와 초기화 단계가 분리되어 진행되므로 ReferenceError (일시적 사각지대 : Temporal Dead Zone)가 발생하며 초기화 이전에 접근할 수 없다고 나온다.

<script>   
   console.log(email);
   let email = 'jiurinie@gmail.com'; // Uncaught ReferenceError: Cannot access 'email' before initialization
   console.log(email);
</script>

이는 마치 let과 const는 호이스팅 현상이 발생하지 않는 것 처럼 보일 수 있으나 아래코드를 확인해보면 호이스팅 현상을 확인할 수 있다.

<script>   
    let email = 'jiurinie@gmail.com'; // 전역 변수

    {
        console.log(email); // Uncaught ReferenceError: Cannot access 'email' before initialization
        let email = 'jiurinie@email.com'; // 지역 변수
    }
</script>

위 코드는 전역변수인 email을 아래 코드블록({})에서 출력할 경우 출력이 정상적으로 될 것으로 예상되나, 오류가 발생한다. 왜냐하면 코드 블록안에 선언된 email(지역변수) 변수 또한 호이스팅되고 코드 블록의 상단부터 초기화가 이루어지는 지점까지 일시적 사각지대(TDZ)에 빠지기 때문이다.

 

이로써 기존 var 키워드와 ES6에 추가된 let, const 키워드에 대해서 알아보았다. var는 버전 문제의 차이가 없다면 사용하지 말고 let과 const 키워드를 사용하자. 변수는 사용 목적에 맞게 재할당이 필요하다면 let을, 필요가 없다면 const로 선언하여 사용하고 변수 선언 시 범위(Scope)를 최대한 작게 생성하여 사용하도록 한다.

728x90

댓글