[TIL / JavaScript] var, let, const의 차이점

[JavaScript] var, let, const의 차이점

중복 선언


  1. var : 중복 선언이 가능하다.
// 첫번째 변수 선언 + 초기화 
var a = 10; 
console.log(a); // 10 

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

// 세번째 변수 선언(초기화X) 
var a; 
console.log(a); // 20
  • var로 선언한 변수는 중복해서 선언과 초기화가 가능하다. → 마지막에 할당된 값이 변수에 저장된다.
  • 기존에 선언해둔 변수의 존재를 잊고 값을 재할당하는 등의 실수가 발생하기 쉽다.
  1. 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
  • 이미 선언한 변수를 다시 선언할 경우, 에러가 발생한다.
  • 코드의 안정성을 높여준다.

재할당


  1. var, let : 값의 재할당이 가능하다.
var a = 10; 
a = 20; 
console.log(a); // 20 

let b = 111; 
b = 222; 
console.log(b); // 222
  1. const : 값의 재할당이 불가능한 상수다.
const c = 111; 
c = 222; // TypeError: Assignment to constant variable.
  • const는 상수를 선언하는 키워드다.

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

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

스코프


  • 스코프(Scope)란 유효한 참조 범위를 말한다.

지역변수와 전역변수

  • 전역변수(Global Variable)는 함수 외부에서 선언된 변수로, 프로그램 전체에서 접근할 수 있는 변수이다.
  • 지역변수(Local Variable)는 함수 내부에서 선언된 변수로, 함수가 실행되면 만들어지고 함수가 종료되면 소멸하는 변수이다. 함수 외부에서는 접근할 수 없다.
  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
  1. let, cost : 블록 레벨 스코프(block-level scope)
  • let, const는 함수 내부는 물론, if문이나 for문 등의 코드 블럭에서 선언된 변수도 지역변수로 취급한다.
if(true) {
	let a = 10; 
	console.log(a); // 10 
} 

console.log(a); // ReferenceError: a is not defined

if문의 블럭 내부에서 let으로 선언된 변수는 외부에서 참조되지 않는다.

호이스팅


  • 호이스팅(Hoisting)이란 일부 표현식이나 선언문 등을 실행 단계에서 해당 Scope의 맨 위로 옮기는 것을 말한다.
  • JavaScript 변수 생성과 초기화(선언과 할당)가 분리되어 진행되기 때문에 발생한다.
  1. var: 변수 호이스팅이 발생한다.

sum이라는 함수를 실행해서 1+3값을 result에 넣으려고 한다.

var result = sum(1,3); 
var sum = function(num1, num2){
   return console.log(num1+num2);  // sum is not a function
}  

에러가 발생한다. sum이라는 함수는 분명 아래 존재하는데 말이다.

var로 선언되어 있는 변수들이 맨 위로 끌어올려진다. 이 때 변수만 선언될 뿐 초기화는 진행되지 않는다.

var result = undefined; 
var sum = undefined; 
result = sum(1,3);  // 여기서 선언된 변수들에 초기화가 이루어진다.
sum = function(num1, num2){ // 마찬가지이다.
   return console.log(num1+num2);
}
  • 변수 호이스팅의 경우 undefiend로 변수 생성이 되지만 함수 호이스팅은 그대로 맨 위로 올라오기 때문에 다르게 동작한다.
var result = sum(1,3); // 이 때는 실행이 된다.
function sum(num1, num2)  // 함수 선언식으로 되어있기 때문에 함수가 그대로 끌어올여진다.
   return console.log(num1+num2);  // 4
}
  • 변수와 함수명이 같을 때 변수에 값이 초기화되어 있으면 변수가 함수를 덮어 씌운다.
var getName = 'olaf';
function getName(){
  console.log('olaf');
}
console.log(typeof getName); // string
  • 변숫 값이 undefiend 로 선언되어 있을 경우 변수를 함수가 덮는다.
var getName; // undefined
function getName() {
     console.log("appear");
}
console.log(typeof getName); // function
  1. let, const: 변수 호이스팅이 다른 방식으로 발생한다.
console.log(a); // ReferenceError: a is not defined 
let a = 10;

1) 코드 실행 전에는 변수 선언만 진행한다.

2) 초기화는 코드 실행 과정에서 변수 선언문을 만났을 때 수행한다.

따라서 마치 호이스팅이 발생하지 않는 것처럼 보인다. → 변수의 선언과 초기화 사이에 일시적으로 변숫 값을 참조할 수 없는 구간을 TDZ(Temporal Dead Zone)라고 한다.

let a = 10; // 전역변수 a선언 
if(true){ 
	console.log(a); // ReferenceError: a is not defined 
	let a = 20; // 지역변수 a 선언 
}

if문 블럭 내부에서 지역변수 a를 다시 선언하니 지역변수 a 앞에서 console.log()로 참조 시 에러가 발생한다. → 지역변수 a가 호이스팅되면서 TDZ 구간이 만들어졌기 때문이다.(지역변수가 전역변수보다 우선 순위를 갖는다.)

P.S.

결론적으로 1순위로 const를 사용하고, 변숫 값을 재할당할 필요가 있을 때 let을 사용하면 될 것 같다. var는 특별한 경우를 제외하고는 가능한 사용하지 않는 추세인 듯 하다. 허용되는 것이 많을수록 버그가 생길 우려도 그만큼 커지기 때문이다😨

참고 문서


좋은 웹페이지 즐겨찾기