JavaScript 익히기 #19 var,let,const

Sunki-Kim·2023년 2월 20일
0

JavaScript 익히기

목록 보기
20/23

앞서 Scope(링크참조)에서 다룬 부분이지만, 자주 나오는 질문이기도 하고 확실하게 알고가는 느낌이기도 하면서,면접 단골질문인 var let const를 명확히 정리해놓고 가고자 따로 작성해보았다.

var는 function-scoped let,const 는 block-scoped라는 큰 차이를 가지고 있다.

var

  • Function-Scoped
var sayHi = 'Hi Sunki'

function greeting() {
    var nice = 'Nice to Meet You'
    console.log(nice)
}
console.log(sayHi) // Hi Sunki
greeting() // Nice to Meet You
console.log(nice) // ReferenceError: nice is not defined

sayHi는 함수 밖에 선언되어있어 전역적으로(코드 전체) 선언이 되어있다.
하지만 함수안에있는 nice는 함수 안에 선언이 되어있어,
함수를 따로 호출하지 않는 이상 함수 밖에서 불러와지지 않고 레퍼런스 에러가 발생한다.

  • 변수 재선언
var sayHello = '안녕 선기'
sayHello = '반가워 선기'

console.log(sayHello) // 반가워 선기

var 변수는 같은 범위라면 언제든지 재선언, 업데이트가 되며, 에러가 발생하지 않는다.

  • 호이스팅
console.log(sunki) //ReferenceError: sunki is not defined

로그를 찍었을때 일반적으로 레퍼런스 에러가 난다.

console.log(sunki) // undefined
var sunki = '내 이름'

var로 변수를 선언하게 되면 해당 범위에서 최상단에 끌어올린거 처럼 작동하여, 초기화(undefined)가 된다.

  • 주의점
var name = 'Sunki'
var age = 31

if (age > 30) {
    var name = '선기!'
}

console.log(name) // 선기!

age가 31이기 때문에 if 조건문이 true가 되어져서, name이 재정의가 되었다. 의도하였다면, 문제가 되진 않겠다만 name이 이미 정의되어있다는 사실을 인지하지 못하면 문제가 될 수 있다. 만약 다른 name이라는 변수를 사용하고 있다면, 의외에 출력물에 버그가 발생할 가능성이 있기때문에, let과 const가 필요하게 되었다.

let

var에서 가지고 있는 문제점을 let이 개선된 부분을 가지고 있어, 선호되는 변수가 된다. let부터는 block-scoped가 적용된다. 이는 {}로 바인딩이 된 청크로, 하나의 블록은 중괄호 안에 적용이 된다. 중괄호 안은 블록범위로 인식한다.

  • block-scoped
let age = 31

if (age > 30) {
    let name = '선기!'
    console.log(name) // 선기!
}

console.log(name) // ReferenceError: name is not defined

let을 사용한 name 변수는 다음과 같이 중괄호 안에서 동작을 하고, 바깥에 사용된 name은 다른 블록범위로 동작이 이루어진다.

  • 업데이트(재할당) 가능, 재선언 불가
let male = 'Man'
let male = 'M' // SyntaxError: Identifier 'male' has already been declared
male = 'M'
console.log(male) // M

같은 범위 내에서 업데이트는 가능하지만, 재선언을 하면 에러가 발생한다.

  • 범위차이 동작
let work = 'ing'
let day = 31

if (day > 30) {
    let work = 'Done!'
    console.log(work) // Done!
}

console.log(work) // ing

아까 var와 큰 차이를 보여주는 동작이다.
let 변수명이 같지만, 블록 스코프로 기준으로 동작하기 때문에, if 내에 있는 work와 중괄호 밖에 있는 work는 다르게 동작한다.

  • 호이스팅
console.log(coffee) // ReferenceError: Cannot access 'coffee' before initialization
let coffee = 'starbucks'

let도 호이스팅이 일어난다. var와 차이점을 가지는건 scope 차이가 있기 때문에, var에서는 undefined로 초기화가 이루어 지지만, let은 레퍼런스 에러가 발생한다.
let은 값을 할당하기 전에 변수가 선언이 되어있어야 한다.

그렇기에 해당 변수에 접근할수 없을때, 발생하는 레퍼런스 에러를 Temporal dead zone (tdz)라고 한다.

const

const도 마찬가지로 블록범위로 적용이 된다.
const가 가진 큰 특징을 알아보자.

const meal = 'bob'
meal = 'ramen' // TypeError: Assignment to constant variable.
const meal = 'kimchi' // SyntaxError: Identifier 'meal' has already been declared

const는 재선언도 업데이트(재할당)도 모두 불가능하다.
선언과 동시에 할당이 같이 해줘야 한다.
따라서, 데이터가 불변하는 고정적인 부분을 선언할때 사용하길 권장하는 편이다. 하지만 특징적인 부분이 속성은 변경이 가능하다.

  • 속성
const dinner = {
    bob: '햇반',
    banchan: '스팸'
}

dinner.banchan = '김치찌개'

console.log(dinner) // { bob: '햇반', banchan: '김치찌개' }

다음과 같이 개체를 업데이트 하는건 불가능하지만, 그 안에 속성이 업데이트가 되는것은 가능하다.

  • 호이스팅
console.log(noodle) // ReferenceError: Cannot access 'noodle' before initialization
const noodle = '소면'

let 가 마찬가지로 const도 끌어올려지지만 초기화가 동작하지 않아 tdz가 발생한다.

소스코드

profile
당신에게 가치있는 Developer가 되고자

0개의 댓글