[JavaScript]var,let,const의 차이 (+scope,hoisting,변수 생성 단계)

chaewon Im·2022년 2월 20일
0

공부 기록✏️

목록 보기
8/15

차이를 알아보기 전 알아두기!

1.scope(스코프)

스코프란 식별자의 유효 범위를 뜻한다. 선언된 위치에 따라 유효 범위가 달라진다. 전역 변수는 전역 스코프(=전역에서 유효,어디든 참조 가능), 지역 변수는 지역 스코프(=지역+하위 지역에서 유효)를 가진다.

  • 블록 레벨 스코프: 자바스크립트에서 생기는 모든 코드 블록(if,for,while,try/catch 등)은 지역 레벨 스코프를 가진다. 이를 블록 레벨 스코프라고 한다.
  • 함수 레벨 스코프: 함수 코드 블록만을 지역 스코프로 가진다.

2.변수 선언 단계

변수란 하나의 값을 저장하기 위해 확보한 메모리 공간에 주어진 일종의 식별자이다. 기본적으로 [선언 - 초기화 - 할당] 3가지 단계에 걸쳐 생성된다.

  • 선언 단계: var, const, let 키워드를 사용해 변수명을 등록한다. 자바스크립트 엔진에 변수의 존재를 알리는 행위.
  • 초기화 단계: 값을 저장하기 위한 메모리 공간을 확보한다.
  • 할당 단계: 변수 메모리 공간에 저장할 값을 할당한다. 따로 값을 할당하지 않으면 기본적으로 undefined를 할당해 초기화 한다.

3.hoisting(호이스팅)

  • 호이스팅이란, 함수 안에 있는 모든 선언들을 끌어올려 최상단에서 선언하는 것과 같은 현상을 말한다.

  • 그러나 실제로 코드가 끌어올려지는 것은 아니다. 자바스크립트는 코드를 실행하기 전 실행 컨택스트를 위한 과정을 거치는데, 이 때 엔진 내부에서 모든 선언(var,let,const,function,class)을 메모리에 등록한다.

  • 따라서 코드가 실행되기 전 이미 필요한 모든 선언들이 저장되어 있기 때문에, 선언문보다 참조/호출이 먼저 나와도 동작에는 오류가 나지는 않는다.

  • 자바스크립트 동작 과정에 따라 모든 선언에는 호이스팅이 일어난다.

  • 다만 let, const, class를 이용한 선언문은 호이스팅이 발생하지 않는 것처럼 동작한다. 참조 에러가 난다고 호이스팅이 일어나지 않은 것이 아니다. 참조 에러가 나는 이유는 메모리에 공간만 생기고, 값을 초기화하지 않기 때문.


💡var

1.함수 레벨 스코프를 가진다.

  • 함수의 코드 블록만을 스코프로 가진다.
  • 함수 내에서 선언된 변수는 함수 내에서만 유효하고, 함수 외부에서는 참조할 수 없다.
  • 함수 외부에서 선언한 변수는 모두 전역 변수이다.

2.재선언(중복 선언), 재할당이 모두 가능하다.

var name = '김철수'
var name = '신짱구'

console.log(name) //'신짱구'
  • 이미 선언한 변수를 재선언해도 아무 에러가 발생하지 않는다. 재할당 & 재선언(중복선언)이 모두 가능하다.
  • 변수 선언이 유연하므로 편하게 느껴지지만, 문제가 발생할 확률이 높다. 거대한 프로그램이라고 가정했을 때 다른 어딘가에서 이미 선언한 변수를 또 선언해도 발견하지 못할 수 있다.

변수 호이스팅

  • var는 변수 선언 시 선언 단계와 초기화 단계가 한번에 이루어진다.
  • 이 때 따로 값을 할당하지 않으면 undefined로 초기화한다. undefined라는 초기화 된 값이 존재하기 때문에 var는 선언문 이전에 변수를 참조해도 참조 에러가 발생하지 않는다. (let,const는 선언시 값을 초기화하지 않는다.)
name = '신짱구'

console.log(name)
var name = ''

💡let,const

- let/const 공통 속성 -

1.블록 레벨 스코프를 가진다.

  • 블록 레벨 스코프를 가지므로, 블록에서 유효하다.

2.TDZ(Temporal Dead Zone)속성을 가진다.

  • TDZ란 직역하면 일시적 사각지대라는 뜻인데, 스코프의 시작점부터 초기화 시작점까지의 구간을 뜻한다.

  • 위에서 얘기한 것 처럼 자바스크립트는 코드를 실행 전 모든 선언을 메모리에 등록해 놓는데, 이 때 let,const는 메모리에 공간만 만들고 초기화를 하지 않는다.

  • 이 초기화가 되기 전 까지의 상태가 TDZ이다.

3.호이스팅이 발생하지 않는 것처럼 동작한다.

  • let,const 키워드는 TDZ 속성을 가지기 때문에 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생한다.
  • 이는 자바스크립트에서 초기화가 되지 않은 변수는 참조할 수 없기 때문이다.
  • 따라서 초기화가 되지 않은 것일 뿐, 호이스팅이 발생하지 않은 것이 아니다.
console.log(name)
//ReferenceError

let name = '김철수'

4.재선언이 불가능하다.

  • 만약 이미 let,const 키워드로 선언한 변수가 있다면 같은 이름의 변수를 선언할 수 없다.
let name = '김철수'
let name = '신짱구'

const age = 5
const age = 29

//재선언 불가, 에러 발생

- let/const 차이 -

let-재할당이 가능하다./const-재할당이 불가능하다.

  • let은 변수가 선언되어있다면 재할당이 가능하다.
  • const는 재할당이 불가능하다. 상수같은 존재.
let puppy = '흰둥이'
puppy = '감자'

const name = '김철수'
name = '신짱구'
//const는 재할당 불가능.Assignment to constant variable
  • 이러한 특징 때문에 const는 객체 타입으로도 많이 사용된다. 이 때 person 변수를 직접적으로 바꾸는 동작은 불가능하다.
const person = {
	name:'신짱구',
    age:'5',
}

person.name = '봉미선'
person.name = 29
//객체 자체가 아닌 내부의 값반 바꾸는 것이기 때문에 정상 동작이 가능하다.

person.push({
	name:'신형만',
    age:'35',
})
//person

정리

var보다는 let 또는 const를 쓰는 방식을 권장하고 있다.

  • 재할당이 필요한 경우에 한정해 let을 쓴다. 이 때 변수 스코프는 최대한 좁게 만든다.
  • 그래도 웬만해서는 const를 쓰는것을 지향한다. 객체, 상수 등에 주로 사용한다.
profile
빙글빙글 FE 개발자

0개의 댓글