본문 바로가기

프로그래밍/JavaScript

var과 let, const

var

  • var은 스코프 범위가 함수 단위(function scoped)다.
function func() {
    {
        var a = 1;
    }
    console.log(a);
}

func();

 

  • 중괄호로 변수 a가 감싸져 있지만 var는 중괄호로 구별한 것은 무시하고 함수 단위로 스코프가 형성된다. 그렇기 때문에 console.log(a)의 결과가 1이 나오게 된다.
  • 또한 var은 변수가 이미 선언되어 있더라도 밑에서 다시 선언될 경우 이전 내용이 지워지고 새 내용이 들어가게 된다.
  • var을 사용하게 되면 Hoisting문제가 발생할 수 있다.
//var가 hoisting되어 정상적으로 j의 값이 불러와진다.
for (var j = 0; j < 10; j++)
    console.log('j :', j);
console.log('for루프 후 j값은', j);

function counter() {
    for (var i = 0; i < 10; i++)
        console.log('i :', i);
}
counter();
//ReferenceError발생 (i가 정의되지 않았습니다.)
console.log('for루프 후 i값은', i);

 

  • 위 코드의 경우 에러가 발생하는 이유는 counter함수 밖에서 i값을 호출하고자 했기 때문이다. 함수 단위 스코프이기 때문에 함수 밖으로 나오는 순간 i변수의 생명이 다해 소멸했기 때문에 오류가 발생하게 된다.
(function () {
    for (var i = 0; i < 10; i++)
        console.log('i :', i);
})();
//Refference 오류가 발생한다.
console.log('for루프 후 i값은', i);

 

  • IIFE(Immediately-Invoked Function Expression)을 통해 함수 스코프처럼 보이게 만들어줄 수 있다. 하지만 완전히 결과가 같지는 않다.
  • 위 코드에서 var을 제거하고 i를 호출하면 i가 hoisting되어 마치 전역변수처럼 취급된다.
  • var을 사용하는 환경에서 hoisting을 막기 위해서는 상단에 'use strict'를 사용해주어야 한다.
(function () {
    'use strict'
    for (i = 0; i < 10; i++)
        console.log('i :', i);
})()
//Refference 에러가 발생한다.
console.log('for루프 후 i값은', i);

 

  • 변수를 선언하고 사용하는데 너무 많은 것들을 고려해야 하기 때문에 최신의 자바스크립트에서는 사용하지 않는 죽은 방식이다.

 

let, const

  • let과 const는 스코프 범위가 괄호 & 중괄호 단위(block scoped)다.
function func() {
    {
        let a = 1;
    }
    
    console.log(a);
}

func(a);
  • var 예시와 같은 구성이지만 결과는 a가 선언되지 않았다는 레퍼런스 에러가 발생하며 a를 콘솔에 출력하지 못한다.
  • let을 선언한 블록 내에서 바로 호출하지 않는다면 블록을 빠져나감과 동시에 해당 변수의 생명주기는 끝나게 된다.
  • 이는 let이 블록 레벨 스코프이기 때문에 발생하는 것이다.
  • let은 var과는 다른 차이가 변수 재선언이 불가능하다는 것이다. 함께 나온 const와의 차이점은 변수의 immutable여부이며, let은 변수의 재할당이 가능하다.
  • let이나 const도 완전하게 hoisting문제를 해소하지는 못하며 var와는 다르게 블록 단위로 호이스팅이 일어난다.
  • let과 const의 또다른 차이점으로 let은 선언을 먼저한 후 추후에 값을 할당할 수 있지만, const는 선언 당시에 값을할당하지 않으면 오류가 발생한다.
  • 현대의 자바스크립트 코딩 경향은 최우선으로 const를 사용해 변수를 선언하되 어쩔 수 없는 경우에만 let을 사용하는 것을 권장하고 있다. 이는 변수가 프로그래머의 의도와 다르게 변경될 수 있는 가능성을 차단하기 위함이다.
const list = [1, 2, 3, 4];

list.filter(value => value > 1);

 

  • 위 코드의 경우 const로 배열이 선언되었는데 배열의 값이 [2, 3, 4]로 변하게 된다.
  • const는 재할당이 절대 불가능한데 왜 이런 일이 가능한지 의문이 들었던 적이 있었는데 추후에 알게 된 사실로 이는 객체의 주소를 할당했기 때문에 가능한 일이라는 것이었다.
  • 선언된 list에 대한 주소를 const로 선언했지만 내부의 요소들이 바뀌어도 해당 객체를 참조하는 주소값은 변동되지 않기에 값 변조가 가능해지는 것이었다.

'프로그래밍 > JavaScript' 카테고리의 다른 글

자바스크립트 문제 풀이 (2)  (0) 2019.11.28
자바스크립트 문제 풀이 (1)  (0) 2019.11.26
this  (0) 2019.08.21
클로저와 스코프 체인  (0) 2019.08.21
화살표 함수  (0) 2019.08.20