var, let, const 와 Hoisting

var, let, const 차이

var, let, const 사이에는 재선언과 재할당에 차이가 있다.
var 키워드 자체가 관대하게 변수의 값을 재할당하고 선언이 가능함으로써 발생하는 코드상의 문제점 때문에 ES6에서 엄격한 제한하는 let과 const가 추가되었다.

  • var : 재할당 가능, 재선언 가능
var Var = "Var"
console.log(Var) // 'Var'

Var = "This is Var"
console.log(Var) // 'This is Var'

var Var = "This is also Var"
console.log(Var) // 'This is also Var'
  • let : 재할당 가능, 재선언 불가능
let Let = "Let"
console.log(Let) // 'Let'

Let = "This is Let"
console.log(Let) // 'This is Let'

let Let = "This is also Let" // SyntaxError: Identifier 'Let' has already been declared.

var 은 variable, const 는 constant에서 이름을 따왔지만 let 은 키워드가 왜 let 으로 되었는지 궁금해서 찾아보니 대략 이런 내용들이 확인되었다.
https://stackoverflow.com/questions/37916940/why-was-the-name-let-chosen-for-block-scoped-variable-declarations-in-javascri
https://stackoverflow.com/questions/33090193/linguistic-meaning-of-let-variable-in-programming?noredirect=1&lq=1

  • const : 재할당 불가능, 재선언 불가능
const Const = "Const"
console.log(Const) // 'Const'

Const = "This is Const" // TypeError: Assignment to constant variable.

const Const = "This is also Const" // SyntaxError: Identifier 'Const' has already been declared.

Hoisting

Javascript 는 Interpreter에 의해 코드가 한줄씩 순차적으로 실행된다.

console.log(Var) // undefined
var Var = "var";

console.log(Let) // ReferenceError: Let is not defined
let Let = "let";

console.log(Const) // ReferenceError: Const is not defined
const Const = "const";

Function() // 'Function'
function Function(){
  console.log("Function")
}

하지만 첫번째에 var로 생성한 선언문을 보면 Var을 선언하기도 전에 console.log(Var)로 먼저 접근하려고 하면 에러가 발생하지 않고 'undefined'라는 값을 출력한다. 이는 Javascript 엔진에서 코드를 실행하기 전에 모든 선언문을 Scope에 등록하면서 undefined 값을 할당하기 때문이다. 이렇게 변수 선언문이 코드의 제일 위로 끌어 올려진 것처럼 동작하는 것을 Hoisting 이라고 한다.

Javascript 엔진 변수를 3단계로 생성한다.
1. 선언 단계 : 변수를 실행 컨텍스트의 변수 객체에 등록한다. 이 변수 객체는 스코프가 참조하는 대상이 된다.
2. 초기화 단계 : 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 암묵적으로undefined를 최초의 값으로 초기화 한다.
3. 할당 단계 : undefined로 초기화된 변수에 실제 값을 할당한다.
(https://hanamon.kr/javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85%EC%9D%B4%EB%9E%80-hoisting/)

  • var 키워드는 선언 단계와 초기화 단계가 한번에 일어나기 때문에 undefined 값이 할당된다.
console.log(Var) // undefined
var Var = "var";
  • let 과 const 키워드는 선언 단계와 초기화 단계가 분리되어 진행된다. 선언 단계가 먼저 실행되지만 초기화 단계는 변수 선언문에 직접 도달했을 때 실행된다. 그렇기 때문에 변수가 선언은 되더라도 선언문 지점까지 도달하기전 까지 변수를 참조할 수 없고 에러가 발생하는 현상을 '일시적 사각지대 (Temporal Dead Zone:TDZ)' 라고 부른다.
console.log(Let) // ReferenceError: Let is not defined
let Let = "let";

console.log(Const) // ReferenceError: Const is not defined
const Const = "const";

함수 호이스팅

console.log(함수선언문) // ƒ 함수선언문()
console.log(함수표현식) // undefined

console.log(함수선언문()) // '함수 선언문'
console.log(함수표현식()) // TypeError: 함수표현식 is not a function


function 함수선언문(){
  return '함수 선언문'
}

var 함수표현식 = function(){
  return '함수 표현식'
}

console.log(함수선언문()) // '함수 선언문'
console.log(함수표현식()) // '함수 표현식'

위의 예시를 보면 함수 선언문(function 으로 함수를 생성)으로 생성한 함수는 이미 런타임에 함수 객체가 생성되었기 때문에 선언문의 위치보다 그 이전에 호출할 수 있게되고, 함수 표현식(변수로 함수를 생성)으로 생성한 함수는 변수 자체만 평가되어서 var 키워드의 결과와 똑같이 일어난다.


좋은 웹페이지 즐겨찾기