Search
Duplicate

var, let, const 차이점

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
JS
Scrap
태그
9 more properties

변수 선언 방식

1. Var : 중복 선언 가능

var name = 'javascript'; console.log(name); // javascript var name = 'react'; console.log(name); // react
JavaScript
복사
var 로 선언한 변수는 동일한 이름으로 여러 번 중복해서 선언이 가능함. 이와 같은 경우, 마지막에 할당된 값이 변수에 저장됨. 위의 예제를 보면 에러 없이 각기 다른 값이 출력되는 것을 볼 수 있음.
이는 필요할 때마다 변수를 유연하게 사용할 수 있다는 장점이 될 수도 있지만, 기존에 선언해둔 변수의 존재를 잊고 값을 재할당하는 등의 실수가 발생할 가능성이 큼. 특히 코드량이 많아졌을 때, 같은 이름의 변수명이 여러 번 선언되었다면 어디 부분에서 문제가 발생하는지 파악하기 힘들뿐더러 값이 바뀔 우려가 있음.
이를 보완하기 위해 ES6부터 추가된 변수 선언 방식이 letconst 임.

2-1. let : 중복 선언 불가능, 재할당 가능

let name = 'javascript'; console.log(name); // javascript let name = 'react'; console.log(name); // Uncaught SyntaxError: Identifier 'name' has already been declared name = 'vue'; console.log(name); // vue
JavaScript
복사
var 와 다르게 let 은 해당 변수가 이미 선언되었다는 에러 메시지가 출력됨. 이처럼 중복 선언이 불가능함.
name = 'vue' 와 같이 변수 선언 및 초기화 이후 반복해서 다른 값을 재할당 할 수는 있음.

2-2. const : 중복 선언 불가능, 재할당 불가능

const name = 'javascript'; console.log(name); // javascript const name = 'react'; console.log(name); // Uncaught SyntaxError: Identifier 'name' has already been declared name = 'vue'; console.log(name); // Uncaught TypeError: Assignment to constant variable
JavaScript
복사
letconst 의 차이점은 immutable 의 여부임. let 은 변수에 다른 값을 재할당할 수 있지만, const 는 재할당 시 에러 메시지가 출력됨.
function func() { const list = ["A", "B", "C"] list = "D"; console.log(list); // TypeError: Assignment to constant variable list.push("D"); console.log(list); // ["A", "B", "C", "D"] }
JavaScript
복사
이처럼 const 는 constant(상수)를 뜻하기 때문에 한 번만 선언이 가능하며 값을 바꿀 수도 없음. 하지만 위 예제와 같이 배열과 오브젝트의 값을 변경하는 것은 가능함.
결과적으로 const 는 불변을 의미하는 것과 다르게, 값을 재할당하는 코드만 불가능하다고 볼 수 있음.
+) 더 알아보기 : immutable array 를 만드는 방법
const list = ["A", "B", "C"]; const newList = [].concat(list, "D"); // concat(list, 배열에 추가하고자 하는 데이터) console.log(newList); // ["A", "B", "C", "D"]; console.log(list === newList); // false
JavaScript
복사
새롭게 만든 변수에 기존에 존재하던 배열과 객체를 할당할 때, 같은 데이터를 가진 새로운 배열 또는 객체가 생성되는 것이 아닌 원본과 같은 참조를 가지게 됨.
그렇기 때문에 새로 만든 변수의 값을 변경하면 원본 데이터도 바뀌게 되며, 이 경우 원본 데이터가 훼손되지 않도록 유지하는 방법이 필요함. 위 예제와 같이 적용하면 기존 배열의 복사본이 생기는 것이기 때문에 원본에는 영향을 끼치지 않음.
ES6의 spread operator 를 사용하면 손쉽게 immutable array 를 만들 수 있음.

3. 어떻게 사용하면 좋을까?

const 를 기본으로 사용하여 불필요한 변수의 재사용을 방지하고, 재할당이 필요한 경우 let 을 사용하는 것이 좋음.

스코프 (Scope)

스코프란 유효한 참조 범위를 뜻하며, 기존의 방법인 var 로 선언한 변수와 let 또는 const 로 선언한 변수의 스코프는 다름.

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

function func() { if (true) { var a = 5; console.log(a); // 5 } console.log(a); // 5 } func(); // 5 console.log(a); // ReferenceError: a is not defined
JavaScript
복사
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없음. 즉, 함수 내부에서 선언한 변수는 지역 변수이고 함수 외부에서 선언한 변수는 모두 전역 변수로 취급됨.

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

function func() { if (true) { let a = 5; console.log(a); // 5 } console.log(a); // ReferenceError: a is not defined } console.log(a); // ReferenceError: a is not defined
JavaScript
복사
함수, if문, for문, while문, try/catch문 등의 모든 코드 블록 ({...}) 내부에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없음. 즉, 코드 블록 내부에서 선언한 변수는 지역 변수로 취급됨.

호이스팅 (Hoisting)

호이스팅이란 함수 내부에 있는 선언들을 모두 끌어올려 해당 함수 유효 범위의 최상단에 선언하는 것을 뜻함. (실제로 코드가 끌어올려지는 것이 아닌, 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는 과정에서 내부적으로 끌어올려 처리하는 것을 뜻하며 실제 메모리에서는 변화가 없음) => 미리 선언문을 실행해둔다고 이해하면 됨.

1. var, 함수선언문 : 호이스팅이 발생함

/* 변수 호이스팅 */ console.log(a); // undefined var a = 5; console.log(a); // 5 /* foo(); // foo function foo() { console.log("foo"); }
JavaScript
복사
변수 a 가 선언되기 전에 참조되었음에도 에러가 발생하지 않음. 이는 코드 실행 전에 자바스크립트 내부에서 미리 변수를 선언하고 undefined 로 초기화를 해두었기 때문임. 함수선언문 또한 동일하게 선언되기 전 호출됨에도 에러가 발생하지 않음.

2. let, const, 함수표현식 : 호이스팅이 발생하지만, 다른 방식으로 작동됨

/* 변수 호이스팅 */ console.log(a); // ReferenceError: a is not defined let a = 5; console.log(a); // 5 /* 함수 호이스팅 */ foo(); // error var foo = function() { console.log("foo"); }
JavaScript
복사
변수 a 가 선언되기 전에 참조하니 에러가 발생함. 이는 호이스팅이 발생하지 않는 것이 아닌, 변수의 선언과 초기화 사이에 일시적으로 변수 값을 참조할 수 없는 구간인 TDZ(Temporal Dead Zone)에 빠졌기 때문에 보이는 현상임.
함수표현식을 사용하거나 let 또는 const 로 변수를 선언하는 경우, 자바스크립트 내부에서는 코드 실행 전 변수 선언만 해둘뿐 초기화는 코드 실행 과정에서 변수 선언문을 만났을 때 수행함. 그렇기 때문에 호이스팅이 발생하기는 하지만, 값을 참조할 수 없기 때문에 동작하지 않는 것처럼 보이는 것임.
참고 링크