JavaScript에서 변수 선언 방식의 종류

🙋🏻‍♀️·2022년 7월 28일
0

📌JavaScript의 변수 선언 방식

- 변수 선언 방식에는 var,let,const 가 있다.



📌var, let, const 차이점 5가지

  1. 중복선언 가능 여부
  2. 재할당 가능 여부
  3. 변수 스코프 유효범위
  4. 변수 호이스팅 방식
  5. 전역객체 프로퍼티 여부



✅1. 중복선언

✔️1. var: 중복 선언이 가능하다.

// 첫번째 변수 선언+초기화
var a = 10;
console.log(a); // 10

// 두번째 변수 선언+초기화
var a = 20;
console.log(a); // 20

// 세번째 변수 선언(초기화 X)
var a;
console.log(a); // 20

var로 선언한 변수는 중복해서 선언과 초기화가 가능하다.
이 경우에 마지막에 할당된 값이 변수에 저장된다.

단, 초기화 없이 선언만 한 경우엔 선언문 자체가 무시된다.(에러는 발생하지 않음)

기존에 선언해둔 변수의 존재를 까먹고, 값을 재할당하게 되는 등의 실수가 발생하기 쉽다.


✔️2. const, let: 중복 선언이 불가능하다.

// let 중복 선언
let a = 10;
let a = 20; // SyntaxError: Identifier 'a' has already been declared

// const 중복 선언
const b = 10;
const b = 20; // SyntaxError: Identifier 'b' has already been declared

let,const로 선언한 변수는 중복 선언이 불가능하다. 위와 같이 이미 선언한 변수를 다시 선언할 경우, 에러가 발생한다. var에 비해서 코드의 안정성을 높여줄 수 있는 방식으로, 다른 언어를 쓰던 사람들에게도 익숙함.



✅2. 재할당

✔️1. var, let: 재할당이 가능한 변수다.

var a = 10;
a = 20;
console.log(a); // 20

let b = 111;
b = 222;
console.log(b)l // 222

var와 let은 변수를 선언하는 키워드다. 변수 선언 및 초기화 이후에 반복해서 다른 값을 재할당 할 수 있다.


✔️2. const: 재할당이 불가능한 변수다.

const c = 111;
c = 222; // TypeError: Assignment to constant variable.

const는 상수를 선언하는 키워드다. 처음에 선언 및 초기화하고 나면 다른 값을 재할당 할 수 없다.


*const는 처음 선언할 때 반드시 초기화(값 할당)를 해주어야 한다.

const a = 10;
const b; // SyntaxError: Missing initializer in const declaration



✅3. 스코프(Scope)

  • 스코프란 유효한 참조 범위를 말한다. 예를 들어, 함수 내부에서 선언된 변수는 함수 내부에서만 참조가 가능하다. 이 경우 변수의 스코프는 함수 내부로 한정됨.

✔️1. var: 함수 레벨 스코프(function-level scope)

  • var는 함수 내부에 선언된 지역변수로 한정하며, 나머지는 모두 전역변수로 간주한다.
function hello() {
  var a = 10;
  console.log(a);
}
hello() // 10
console.log(a) // ReferenceError: a is not defined

hello 함수 내부에서 선언된 a 변수는 함수 내부에서만 참조가 가능하며, 외부에서 참조시 에러가 발생한다.


📢하지만 함수를 제외한 영역에서 var로 선언한 변수는 '전역변수'로 취급된다.

if(true){
  var a = 10;
  console.log(a) // 10
}
console.log(a) // 10

자바스크립트에선 if문, for문, while문 등의 코드 블럭 내부에서 var로 선언된 변수를 전역변수로 간주한다. 그래서 블럭 외부에서도 어디에서나 참조할 수 있다.

그러나 let과 const는 다름.


✔️2. let, const: 블록 레벨 스코프(block-level scope)

  • let,const는 함수 내부는 물론, if문이나 for문 등의 코드 블럭에서 선언된 변수도 지역변수로 취급한다.
if(true){
  let a = 10;
  console.log(a) // 10
}
console.log(a) // ReferenceError: a is not defined

당연히 함수 내부에서 선언된 변수도 외부에서 참조할 수 없다.
function hello(){
  let a = 10;
  console.log(a)
}
hello() // 10
console.log(a) // ReferenceError: a is not defined



✏️정리

  • var는 함수 내부에 선언된 변수만 지역변수로 인정하는 함수 레벨 스코프이다.
  • let, const는 블록 내부에서 선언된 변수까지도 지역변수로 인정하는 블록 레벨 스코프이다.
    (* 블록은 if문이나 for문 등의 중괄호{}로 둘러싸인 코드 영역을 말함)



✅4. 호이스팅(Hoisting)의 개념

  • 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
  • 뒤에서 선언된 변수도 앞의 코드에서 참조할 수 있게 되는 것.

✔️1. var: 변수 호이스팅이 발생한다.

console.log(a) // undefined
var a = 10;
console.log(a) // 10

뒤에서 선언된 변수 a가 앞에서 참조되었음에도 에러가 발생하지 않음.
코드 실행 전에 자바스크립트 엔진이 미리 1)변수를 선언하고 2)undefined로 초기화 해두었기 때문이다. 이것이 바로 var로 선언된 변수의 호이스팅이다.


✔️2. let, const: 변수 호이스팅이 발생한다. 하지만 다른 방식으로 작동함

console.log(a) // ReferenceError: Cannot access 'a' before initialization
let a = 10;

뒤에서 선언된 변수를 앞에서 참조하려니 에러가 발생함. 이런 현상이 발생하는 이유는 1)변수 선언만 해둠 2)초기화는 코드 실행 과정에서 변수 선언문을 만났을 때 수행함.

위와 같은 이유로 호이스팅이 발생하기는 하지만 값을 참조할 수 없어서 호이스팅이 발생하지 않는 것처럼 보임.



💥TDZ(Temporal Dead Zone)이란?

  • 변수의 선언과 초기화 사이에 일시적으로 변수 값을 참조할 수 없는 구간.
let a = 10; // 전역변수 a 선언
if(true){
  console.log(a); // 10
}

위 코드는 전역변수로 선언된 a의 값 10을 if문 블럭에서 참조하여 출력하고 있음.



let a = 10 // 전역변수 a 선언
if(true){
  console.log(a) // ReferenceError: Cannot access 'a' before initialization
  let a = 20 // 지역변수 a 선언
}

위 코드는 if문 블럭 내부에서 지역변수 a를 다시 선언했다. 이 경우 지역변수 a 앞에서 console.log()로 참조시 에러가 발생한다(*전역변수 a가 있음에도)

왜냐하면 지역변수 a가 호이스팅되면서 TDZ 구간이 만들어졌기 때문이다. 즉 let으로 선언된 변수도 호이스팅이 발생함을 알 수 있음(*참고로 지역변수가 전역변수보다 우선 순위를 가짐)



✅5. 전역객체 프로퍼티 여부

✔️1. var: var로 선언된 변수는 전역객체(브라우저 환경의 경우 window)의 프로퍼티다.

var a = 10
console.log(window.a) // 10
console.log(a) // 10

브라우저 환경(chrome console 등)에서 위 코드를 실행하면 var로 선언한 변수 a는 브라우저 전역객체인 window의 프로퍼티로 할당됨.


✔️2. let, const: let,const로 선언된 변수는 전역객체 프로퍼티가 아니다.

let a = 10;
console.log(window.a) // undefined
console.log(a) // 10

브라우저 환경(chrome console 등)에서 위 코드를 실행하면 var로 선언한 변수 a는 브라우저 전역객체인 window의 프로퍼티로 할당되지 않았음.(window.a = undefined)



🗨️정리

const를 최우선으로 사용하고 let은 변수 값을 재할당할 필요가 있을 때만 사용하자




0개의 댓글