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

JUNGHUN KIM·2021년 12월 28일
0

기존 자바스크립트에서는 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개의 댓글

관련 채용 정보