본문 바로가기
Programing/Javascript

[JavaScript] var, let, const 차이점을 정리해보겠습니다.

by 멍멍돌이야 2022. 6. 15.
반응형
자바스크립트는 진화하고 있습니다.  하나의 결과를 갖고 여러 스타일의 코딩 방법이 사용되고, 개발자의 코드 스타일이 다르기 때문에 수많은 형태의 코드를 만들 수 있습니다.
var로 기본 변수를 쭉 사용해왔지만, let/const를 알게 되었을 때 잘못된 코드를 여태 쥐어짜고 있었구나 느끼게 되었습니다. var let const에 관하여 정리된 글을 기반으로 다시 정리해보겠습니다.
 

목차

     

    var를 사용하여 함수 수준 변수 선언

    과거에 변수 선언을 하게 되는 가장 일반적인 방법이며, var 선언한 변수는 함수 수준입니다.
    즉, 선언된 위치에 함수를 그대로 두는 한 변수는 유효하지 않게 됩니다.
    예를 들면 다음과 같습니다. 
    function foo() {
      var a = 23;
      console.log(a);
    }
    
    foo();
    console.log(a);
           
    실행 결과는 다음과 같습니다. 
    23
    Uncaught ReferenceError: a is not defined
    a정의되지 않은 식별자 오류가 발생합니다.  왜냐하면 a기능에 있습니다.
    foo함수에서 선언한 a 변수는 외부에서 액세스 됩니다.
     

    전역 변수

    var변수를 함수밖에서 사용하는 경우 프로그램 어디에서나 액세스 할수 있는 전역 변수가 됩니다.
    예를 들면 다음과 같습니다.
    var a = 23;
    
    function foo() {
    console.log(a);
    a = 24;
    }
    
    foo();
    console.log(a);
    실행 결과는 다음과 같습니다. 
    23
    24

     

    초기값 분리 선언 및 설정

    다음과 같이 선언을 분리하고 초기 값을 설정할 수도 있지만 반드시 동시에는 아닐 수도 있습니다. 
    var a;
    a = 23;
    console.log(a);
    변수를 한 곳에서 선언하고 싶지만 변수가 사용될 때만 값을 설정하려는 경우에 유용할 수 있습니다.

     

    반복 선언

    새 값이 설정되지 않는 한 동일한 변수를 반복적으로 선언할 수도 있습니다.
    예를 들어 다음과 같이 원래 값이 그대로 유지됩니다. 
    var a = 23;
    console.log(a);
    var a;
    console.log(a);
    var a = 24;
    console.log(a);
    실행 결과는 다음과 같습니다. 
    23
    23
    24
    다시 선언되었지만 세 번째 줄 a, 그러나 값이 재설정되지 않으므로 a값은 23 입니다.

     

    가변 호이스팅(variable hoisting)

    무엇에 쓰이는지 모르는 변수가 있지만 많은 사람들이 그것을 사용하여 다른 사람의 기능을 테스트하는 데 사용하는 것을 좋아합니다. variable hoisting),  변수를 선언하는 동작은 다른 프로그램을 실행하기 전에 완료되도록 승격됩니다. 즉, 변수의 유효 범위에 들어갈 때 첫 번째  프로그램이 실행되기 전에 변수가 선언됩니다. 따라서 첫 번째 스트로크가 실행될 때 변수는 이미 존재합니다. 예: 
    console.log(a);
    var a = 23;
    console.log(a);
          

     

    실행 결과는 다음과 같습니다. 

    undefined
    23

    변수는 첫 번째 패스가 실행되기 전에 선언되기 때문에 첫 번째 패스로 인해 변수가 선언되지 않았다는 오류가 발생하지 않습니다. 그러나 var선언된 변수, 변수승격은 변수를 먼저 선언만 하고 초기값을 설정하는 프로그램을 실행하지 않으며 위의 예에서는 실행되지 않습니다. a = 23, 그러나 초기 값을 undefined, 따라서 첫 번째 줄이 인쇄된 것을 볼 수 있습니다. a의 값은 undefined. 변수는 두 번째 줄이 실행될 때까지 설정되지 않습니다. a는 23이므로 세 번째 줄은 23을 인쇄합니다.

     

     

    전역 변수는 전역 개체의 속성이 됩니다.

    var선언된 전역 변수는 전역 개체의 속성이 됩니다.
    예를 들면 다음과 같습니다. 
    var a = 23;
    console.log(globalThis.a);
    실행 결과는 다음과 같습니다. 
    23
    그러나 이 속성은 다음과 같이 구성할 수 없습니다.
    예를 들어 다음 프로그램에서 제거(delete)하면 오류가 발생하지 않지만 delete는 작동하지 않았습니다. 
    var a = 23;
    delete a;
    delete globalThis.a;
    console.log(a);
    출력된 결과 값은 정확리 23입니다.
    23
     
    엄격 모드(use strict)에 있는 경우 오류 메시지가 표시됩니다. 
    'use strict';
    
    var a = 23;
    delete globalThis.a;
    console.log(a);
    실행 결과는 다음과 같습니다. 
    Uncaught TypeError: property "a" is non-configurable and can't be deleted

     

    let으로 블록 수준 변수 선언하기

    소위 블록은 다음을 사용하여 한 쌍의 중괄호로 둘러싸인 영역입니다. let선언된 변수는 그것이 위치한 블록 외부에 있는 한 유효하지 않습니다.
     
    예를 들면 다음과 같습니다. 
    {
    let a = 23;
    console.log(a);
    }
    
    console.log(a);
    실행 결과는 다음과 같습니다. 
    23
    Uncaught ReferenceError: a is not defined
    2차 사용으로 인해 a변수가 선언된 블록을 떠났으므로 변수 a유효하지 않습니다. 정의되지 않은 식별자 오류가 발생합니다.

     

    블록 구별

    대부분의 경우 블록을 쉽게 식별할 수 있지만 다음과 같은 경우 for에 대한 설명에서 초기 설정도 블록의 일부이므로 초기 설정에서 선언된 변수는 for종료 후에도 실패합니다.
    예를 들면 다음과 같습니다. 
    for(let i = 0;i < 2;i++)
    {
    console.log(i);
    }
    
    console.log(i);
     
    실행 결과는 다음과 같습니다. 
    0
    1
    Uncaught ReferenceError: i is not defined
     
    var변수를 사용하는 경우 선언해도 함수의 범위를 벗어나지 않기 때문에 오류가 발생하지 않습니다.
    예를 들면 다음과 같습니다. 
    for(var i = 0;i < 2;i++)
    {
    console.log(i);
    }
    
    console.log(i);
    i값 실행 결과는 최종적으로 루프의 끝에서 인쇄됩니다.
    0
    1
    2
            

    전역 변수

    모든 블록 외부에서 사용 let생성된 변수는 전역 변수이기도 하며 프로그램의 어디에서나 액세스할 수 있습니다.
    예를 들면 다음과 같습니다. 
    let i = 0;
    
    for(i = 0;i < 2;i++) {}
    
    console.log(i);
    결과는 다음과 같습니다. 
    2

     

    변수는 반복적으로 선언할 수 없습니다.

    let에 의해 선언된 변수에도 변수 승격 기능이 있지만 초기값을 설정하지 않고 변수를 사용하기 전에 반드시 변수를 통과시켜야 합니다.
    let선언은 다음과 같이 선언합니다. 
    console.log(a);
    let a = 0;
     
    실행되면 오류가 발생합니다. 
    Uncaught ReferenceError: can't access lexical declaration 'a' before initialization
    a의 초기 값이 설정되기 전에는 선언된 변수에 액세스할 수 없음을 나타냅니다.

     

    let으로 선언된 변수는 전역 객체의 속성이 되지 않습니다.

    let에 의해 선언된 변수는 다음으로 시작하지 않는 것으로 보입니다. var선언된 변수는 전역 개체의 속성이 됩니다.
    예를 들면 다음과 같습니다. 
    let a = 23;
    console.log(globalThis.a);

    실행될 때 출력되는 것은 undefined으로 출력됩니다.

    undefined
    a는 전역 개체에 없음을 나타냅니다.
     

    const를 사용하여 변경할 수 없는 변수 선언

    const말 그대로 변경할 수 없으며 즉, 상수라고 정의를 합니다. 다음 예를 살펴보겠습니다. 
    const a = 23;
    console.log(a);
    a = 24;
    실행 후는 다음과 같습니다. 
    23
    Uncaught TypeError: invalid assignment to const 'a'
    세 번째 줄에서 const선언된 상수의 내용을 설정하려고 하면 설정할 수 없다는 오류가 발생합니다.

     

    상수 선언 시 반드시 값 설정

    const상수에 의해 선언할 때 초기값을 함께 설정해야 하며, 초기값을 따로 선언하고 설정할 수 없습니다.
    예를 들어 다음과 같은 경우 오류가 발생합니다. 
    const a;
    a = 23;
    console.log(a);
    실행 결과는 다음과 같습니다. 
    Uncaught SyntaxError: missing = in const declaration
    const선언할 때 초기 값이 누락되었습니다. 오류 메시지를 알려줍니다.
     

    상수가 참조하는 객체 변경

    변경할 수 없다는 점에 특히 유의하십시오. const선언된 상수는 상수 자체를 재설정할 수 없음을 의미합니다. 상수의 내용이 객체인 경우에는 객체의 속성값을 변경할 수 있습니다.
    예를 들면 다음과 같습니다. 
    const a = {name: "John"};
    a.name = "Mary";
    console.log(a);
     
    실행 결과는 다음과 같습니다. 
    Object { name: "Mary" }
    상수 객체안의 내용이 변경되기 때문에 a, 성공적으로 실행할 수 있습니다. 같은 방식으로 상수의 내용이 배열이면 배열의 항목을 변경할 수도 있습니다. 
    const a = [1, 2, 3];
    a.push(4);
    a[0] = 10;
    console.log(a);
    실행 결과는 다음과 같습니다. 
    Array(4) [ 10, 2, 3, 4 ]
    값을 재설정할 수 없을 뿐만 아니라, const 그리고 let 그것은 동일합니다.

     

     

    선언하지 않고 직접 변수 설정

    변수 값을 전혀 선언하지 않고 설정하는  프로그램도 다음과 같이 볼수 있습니다.
    a = 23;
    console.log(a);
    a값은 오류 없이 실행되고 올바르게 출력됩니다.
    23
    원하는 대로 함수나 블록에서 직접 이 작업을 수행할 수도 있습니다. 
    function foo() {
    a = 23
    }
    
    {
    b = 24
    }
    
    foo()
    console.log(a);
    console.log(b);
    실행 결과는 다음과 같습니다. 
    23
    24
    a 그리고 b 변수는 블록으로 설정되어 있지만, 둘 다 어디에서나 사용할 수 있는 전역 변수가 됩니다.
     

    선언되지 않은 변수는 실제로 전역 개체의 속성입니다.

    이전 예제의 결과에 대한 이유는 JavaScript가 식별자를 볼 때 이름과 일치하는 선언이 있는지 확인하기 위해 계층별로 조사하기 때문입니다.
    예를 들면 다음과 같습니다. 
    let a = 23
    
    function foo() {
    	console.log(a)
    	b = 24;
    	{
    		c = 25;
    		{
    			console.log(b)
    		}
    	}
    }
    
    foo();
    실행 결과는 다음과 같습니다. 
    23
    24
    foo함수 위에 a 변수가 선언되었기 때문에 전역 변수가 됩니다.  b 변수 또한 상위 블록에 선언되어 하위블록에서 사용이 되며 b변수는 전역개체 속성에 찾을수 없습니다.
    alert('call globalThis.alert');
    globalThis.alert('property of globalThis');
    위의 두 가지 작성 방법은 JavaScript가 볼 때 실제로 동일합니다. alert, 당신은 프로그램이 정의하지 않는다는 것을 알게 될 것입니다
    alert함수는 프로그램에서 정의하지 않았지만, 전역개체로 인식되며, globalThis에 의해 호출됩니다.
    선언되지 않은 식별자(함수, 변수)에 대해서 JavaScript는 전역 개체의 속성으로 설정/처리합니다.
    예를 들면 다음과 같습니다. 
    a = 23;
    globalThis.b = 24;
    console.log(globalThis.a);
    console.log(b);
    실행 결과는 다음과 같습니다. 
    23
    24
    엄격 모드(use strict)를 설정하게되면. 다음과 같이 선언하지않는 a를 사용하게되면 오류가 발생합니다.
    'use strict'
    a = 23;
    console.log(a);
    실행되면 오류가 발생합니다. 
    Uncaught ReferenceError: assignment to undeclared variable a

     

    var 전역 변수와 순수 전역 객체 속성의 차이점

    당신이 상상할 수 있듯이, 그것은 이전에 언급되지 않았습니다. var선언된 전역 변수도 전역 객체의 속성이 됩니다. 이것은 방금 언급한 순수 전역 객체의 속성과 동일하지 않습니까? 내가 전에 말한 것을 기억하십시오. var선언된 전역 변수는 전역 개체에서 설정할 수 없는 속성이 되며 특정 성능은 사용할 수 없다는 것입니다. delete제거하지만 순수한 전역 개체의 속성인 경우 다음을 사용할 수 있습니다. delete예를 들어 다음을 제거하십시오. 
    globalThis.a = 23
    console.log(a)
    delete a
    console.log(a)
    실행 결과는 다음과 같습니다. 
    23
    Uncaught ReferenceError: a is not defined
    두 번째 출력 a, 세 번째 줄에서 정의되지 않은 식별자 a를 제거하면 오류가 발생합니다.
    var선언된 전역변수는 삭제가 가능하며 프로그램 어느 곳에서나 접근하여 살제가 가능합니다.

     

    결론

    참고된 글을 바탕으로 내용을 정리하다 보니, var, let, const에 대해서 몰랐던 사실이 정리가 되었습니다.
    오류를 피하기 위해서는 var를 사용하면 안된다고 판단이 되며. const, let만 사용해야겠습니다.
    까면 깔수록 어려운 javascript........세심한 코딩을 하게만드네요.

     

     
     
     

     

     
     
     
     
     
    참고: https://dev.to/codemee/javascript-de-var-let-yu-const-4e61
     

     

    728x90
    반응형

    댓글