var, let, const의 차이점

Deah (김준희)·2023년 11월 8일
0

JavaScript

목록 보기
4/5
post-thumbnail

var

var 변수가 함수 외부에서 선언될 때 var의 스코프(scope)는 전역입니다.
var로 선언된 모든 변수를 윈도우 전체에서 사용할 수 있는 것입니다.

var a = 1;

function print() {
	console.log(a);
}

print();   // 1

이렇게 함수 바깥에서 선언된 변수 a를 print() 함수 내부에서도 접근할 수 있는데,
가능한 이유는 스코프 체이닝(scope chaning) 때문입니다.

스코프 체이닝이란 변수를 찾을 때 먼저 자신이 속한 스코프에서 찾고,
없을 경우 상위 스코프로 올라가면서 찾는 현상을 말합니다.

var 변수가 함수 내부에서 선언될 때에는 스코프가 함수 범위로 한정됩니다.
함수 내부에서만 해당 변수에 접근할 수 있고, 사용할 수 있습니다.

var a = 'global';

function print() {
	var b = 'local';
	console.log(b);
}

print();   // local

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

위 예제에서 변수 bprint 함수 내부에서 선언되었기 때문에 print 함수 내부에서만 접근하고 사용할 수 있습니다.
때문에 print 함수 바깥에서 작성된 console.log(b)는 값을 제대로 출력할 수 없고 에러가 발생합니다.

var로 선언한 변수는 재선언과 재할당이 가능합니다.
같은 변수를 다시 선언하거나, 같은 변수에 다른 값을 할당해도 오류가 발생하지 않아 유연한 사용이 가능합니다.

var a = 'hi';
var a = 'hello';

console.log(a);   // hello
var a = 'hello';
a = 'world';

console.log(a);   // world

var를 사용하여 변수 선언을 할 경우 유연한 사용으로 편리할 수 있지만, 프로젝트 규모가 커지거나 코드량이 많아진다면 해당 변수가 어디에서 어떻게 사용되고 변하는지 파악하기 힘들어질 수 있으며 이로 인해 개발자가 예상하지 못한 사이드 이펙트가 발생할 수 있습니다. 이러한 이유로 ES2015(ES6) 이후 변수 선언의 단점을 보완하기 위해 let과 const가 새로운 변수 선언 방식으로 추가되었습니다.


let

let은 블록 스코프(block scope)의 범위를 가진 지역 변수를 선언합니다.
하나의 블록은 중괄호({ })로 감싸져 있으며, 중괄호 안에 있는 것은 모두 블록 범위입니다.
let으로 선언된 변수는 해당 블록 내에서만 접근하고 사용할 수 있습니다.

let num = 123;
let count = 7;

if (count > 3) {
	let fruits = 'banana';
	console.log(fruits);
}

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

중괄호로 감싸진 if문 내에서 선언된 변수 fruits는 해당 블록 범위인 if문 안에서만 접근과 사용이 가능합니다.
때문에 블록 범위 바깥에서 사용된 console.log(fruits) 에서는 에러가 발생합니다.

let으로 선언한 변수는 재선언은 불가능하지만, 재할당이 가능합니다.
동일한 이름의 변수가 다른 스코프를 가진다면, 즉 다른 범위 내에서 정의된다면 재선언도 가능합니다.
재선언이 가능한 이유는 두 변수의 스코프가 달라 다른 변수로 취급되기 때문입니다.

let a = 'hi';
let a = 'hello';   // SyntaxError: Identifier 'test' has already been declared
let a = 'hi';

if (true) {
	let a = 'hello';
	console.log(a);   // hello
}

console.log(a);   // hi
let a = 'hello';
a = 'world';

console.log(a);   // world

const

const는 블록 범위(block scope)의 범위를 가진 상수를 선언합니다.
var와 let으로 변수를 선언할 때, 변수에 값을 초기화(할당)하지 않은 상태로 선언할 수 있지만
const의 경우 변수의 선언과 함께 값을 무조건 초기화(할당)해야 합니다.

var apple;
let apple;

const apple;   // SyntaxError: Missing initializer in const declaration

const로 선언한 상수는 재선언과 재할당이 모두 불가능합니다.

const a = 'hi';
const a = 'hello';   // SyntaxError: Identifier 'ggg' has already been declared
const a = 'hi';
a = 'hello';   // TypeError: Assignment to constant variable

그러나 const로 선언된 객체의 경우 내부 속성값에 한하여 재할당을 할 수 있습니다.

const fruits = {
	apple: '사과',
	banana: '바나나',
	cherry: '체리',
}

fruits.apple = '애플';

console.log(fruits.apple);   // 애플

대신 객체 자체를 업데이트 할 수는 없습니다.

const fruits = {
	apple: '사과',
	banana: '바나나',
	cherry: '체리',
}

fruits = {
	melon: '멜론',
	fig: '무화과',
}

// TypeError: Assignment to constant variable.

정리

  • var로 선언한 변수는 전역 스코프(global scope) 혹은 함수 스코프(functional scope)를 가집니다.
  • letconst로 선언한 변수/상수의 스코프는 블록 스코프(block scope)입니다.
  • var로 선언한 변수는 재할당과 재선언이 가능한 반면에, let으로 선언한 변수는 재할당만 가능합니다.
  • const로 선언한 상수는 재할당과 재선언이 모두 불가능합니다.
  • 세 가지의 변수 선언 모두 최상위로 호이스팅 되며,
    var 변수의 경우 undefined로 초기화되지만, letconst는 초기화되지 않습니다.
  • varlet은 변수에 값을 초기화(할당)하지 않은 상태로 선언만 할 수 있지만,
    const의 경우 선언과 동시에 값을 초기화(할당)해야 합니다.
profile
기록 중독 개발자의 기록하는 습관

0개의 댓글