let, var, const의 차이점과 호이스팅 (Hoisting)

JUNGHUN KIM·2021년 12월 28일

기존 자바스크립트에서는 var로 변수 선언이 가능하였지만,
var의 한계점으로 인해 ES6부터는 const와 let이 나오게 되었다.(변수의 재선언과 호이스팅을 방지하기 위해)

본격적으로 var,const,let에 대해서 알아보기 위해서는
우선 자바스크립트에서 사용되는 변수가 무엇인지 알아야 된다.

변수(variable)


  • 하나의 값을 저장하기 위해 확보한 메모리 공간 자체, 그 메모리 공간을 식별하기 위해 붙인 이름.
  • 자바스크립트에서는 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조하지 않고, 변수를 통해 값에 접근
  • 변수는 변수의 값이 아닌 참조하는 메모리 주소를 기억하고 있으며, 변수를 사용하게 될 경우, 자바스크립트 엔진이 변수와 매핑된 메모리 주소를 통해 저장된 값을 반환
const name = 'Junghun'
//변수명(식별자) : name
//변수 값(저장된 값) : 'Junghun'
//해당 값의 위치(메모리주소) : 눈에보이지는 않지만, 힙(heap)에 저장됨
              		//지금은 간단하게 0012CCGWH80 이라고 하자. 

변수 선언의 3단계

  • declaration (선언) : 변수를 선언하고 자바스크립트 엔진에서 알리는 것
  • initailzation (초기화) : 변수를 선언하면 자바스크립트는 해당 변수를 인식하고 되고 변수에 값을 저장할 수 있게끔 메모리 공간을 만들게 되는데 초기값으로 undefined값을 할당해 초기화
  • Assignment(할당) : 변수에 값을 저장하는 것.
let name   
console.log(name) //  undefined --> 선언, 초기화까지 완료된 상태
let age = 1 
console.log(age) // 1 --> 선언 초기화 할당까지 다 된 상태 

var

  • 재선언 및 재할당이 가능 / 같은 이름의 변수명을 여러번 쓰게되면 추후 디버깅적으로 어려움이 큼(이것을 보완하기 위해 let const가 ES6부터 추가)
var test = 123
console.log(test) // 123

var test = 456
console.log(test) //456
  • 함수 레벨 스코프(function{},함수이외의 if,for 등에서 선언된 변수는 전역 변수가 된다)
//함수가 아닌 곳에서 a라는 변수를 선언하였기 때문에 전역에서 console.log(a)사용이 가능
if(true){
    var a = 1
}
console.log(a) // 1

//함수 레벨 스코프이기 때문에 함수 a에서 선언된 변수 b는 전역에서 사용이 불가능
function a(){
    var b = 2
    return 1
}
console.log(b) // ReferenceError: b is not defined

let

  • 재선언 불가능(중복 선언시 SyntaxError발생)
// SyntaxError : Identifier 'test' has already been declared 
let test = 123
console.log(test)

let test = 456 
  • 재할당 가능
let test = 123
test = 456
console.log(test) // 456
  • 블록 레벨 스코프({})
if(true){
    let a = 1
}
console.log(a) // ReferenceError: a is not defined

function a(){
    let b = 2
    return 1
}

console.log(b) // ReferenceError: b is not defined
  • 선언과 초기화가 동시에 이루어짐
var a
console.log(a) // undefined  --> 선언과 동시에 undefined로 초기화가 이루어짐

console.log(a)
var a // undefined --> 호이스팅으로 인해 코드가 선언문이 먼저 실행되어 이러한 결과가 나옴.

const

  • 재선언, 재할당 불가능한 상수 (const의 경우 선언시 초기화와 값 할당을 해주어야 함, 선언만 할경우 에러 발생)
const a  // SyntaxError: Missing initializer in const declaration
  • 블록 레벨 스코프({})

호이스팅

  • 변수 선언은 코드가 실행될때 이루어지는것이 아닌, 이전 단계에서 실행.
    자바스크립트는 코드를 실행하기 전 모든 선언문(변수선언문,함수선언문 등)이 어디에 있던간에 먼저 찾아내 실행하게 되며, 코드보다 먼저 선언문이 실행되는 특징을 호이스팅이라고 함.

다른 말로는, 코드 실행전 모든 선언문을 유효범위(스코프)의 최상단으로 끌어올리는 행위라고 보면 됨.

  • 자바스크립트의 모든 선언에는 호이스팅이 발생하지만 let, const를 이용한 선언문에서는 호이스팅이 발생하지 않은것 처럼 보임
  • var의 경우 변수 선언시 선언과 초기화(undefined)를 동시에 진행하여 변수 선언 이전에 해당 변수를 참조하게 될경우 undefined가 출력(초기화한 상태로 메모리에 저장)
  • let, const의 경우 변수 선언시 초기화를 하지 않음. 해당 변수 선언 이전에 해당 변수를 참조하게 될 경우 참조에러(ReferenceError)발생(초기화하지 않은 상태로 메모리에 저장), 이는 let, const로 선언된 변수는 스코프 시작에서 변수의 선언까지 일시적 사각지대(Temporal Dead Zone)에 빠지기 때문(초기화 하지 않으면, 변수를 참조 할 수 없음.)

호이스팅의 예시

  • 변수 선언에서의 호이스팅
  • var를 사용하였을 경우의 호이스팅 예시
console.log(a); // 선언 + 초기화 된 상태이므로 undefined
text = 'junghun!'; // (선언 + 초기화 + 할당 된 상태)
var a;
console.log(a); // junghun!
  • let을 사용하였을 경우의 호이스팅 예시
console.log(text); // (선언은 되었지만 초기화가 안되서 참조 불가능 -> 에러남)
let text; // 여기서 초기화 단계가 실행됨
  • 함수 선언에서의 호이스팅
foo1(); // Hello --> 함수 선언문에서는 호이스팅 일어난다.(모든 선언문은 호이스팅이 발생함) 
console.log(foo2) // undefined --> var의 경우 선언과 동시에 초기화가 되므로 undefined
foo2(); // foo2라는 변수가 undefined로 초기화는 되었지만 함수가 할당이 되지 않았기 때문에 에러 발생 
function foo1() {
  console.log('Hello');
}
var foo2 = function() {
  console.log('world');
}

참조 레퍼런스


https://www.howdy-mj.me/javascript/var-let-const/

https://velog.io/@gkdlvj1214/%EB%B3%80%EC%88%98-%EC%84%A0%EC%96%B8-%EC%B4%88%EA%B8%B0%ED%99%94-%ED%95%A0%EB%8B%B9-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85

https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/

profile
개발자가 되고 싶은 일문학도

0개의 댓글