1. 변수 선언 방식
var : 변수 재선언 가능 / 재할당 가능
var abc = 1;
console.log(abc); // 1
var abc = 2;
console.log(abc); // 2
var abc;
console.log(abc); // 2
abc = 3;
console.log(abc); // 3
- var로 변수를 재 선언할 시, 변수명이 겹침에도 에러가 없이 변수가 선언이 됩니다.
- 기존에 있던 변수를 초기화하고 선언하는 게 되는데 코드량이 많아지게 되면 이 변수명이 다시 사용되는 상황에 에러가 없이 덮어씌워버리니 파악이 힘들어지는 상황이 있을 수 있습니다.
let : 변수 재선언 불가능 / 재할당 가능
let abc = "one"
console.log(abc); // "one"
abc = "two"
console.log(abc); // "two"
let abc = "three"
console.log(abc); // Uncaught SyntaxError: Identifier 'abc' has already been declared
- let으로 변수를 재 선언할 시 오류가 나며 수행을 하지 않습니다.
- 변수에 재할당을 할 시 값이 변경됩니다.
const : 변수 재선언 불가능 / 재할당 불가능
const abc = "abcd";
console.log(abc) // "abcd"
const abc = "efgh";
console.log(abc) // Uncaught SyntaxError: Identifier 'name' has already been declared
abc = "xyz";
console.log(abc) // Uncaught TypeError: Assignment to constant variable
- const로 변수를 재 선언할 시 오류가 나며 수행을 하지 않습니다.
- 변수에 재할당을 할 시 값이 변경되지 않습니다.
- const는 값이 고정되는 변수 선언 방식(상수)이며 const 변수에 object를 담으면 오브젝트 내의 데이터는 변경이 가능합니다. object 내의 값이 변경되더라도 할당된 주솟값은 변경되지 않습니다.
2. 스코프(Scope)
- 스코프란 유효한 참조 범위를 뜻하며 var , let , const로 선언한 변수마다 스코프는 다릅니다.
var : 함수 레벨 스코프 (function-level scope)
var abc = 1;
function logFunc() {
var bcd = 1;
console.log(abc)
}
logFunc() // 1
console.log(bcd) // error
if(true){
var name = 'voler';
}
console.log(name); // "voler"
- var는 함수의 코드 블록만을 하는 스코프로 , 함수 내부 이외에 생성한 변수는 모두 전역 변수가 되어 전역 변수가 남발될 가능성이 있습니다.
let,const : 블록 레벨 스코프 (block-level scope)
function logFunc() {
if(true){
let abc = 1;
console.log(abc) // 1
}
console.log(abc) // error
}
console.log(abc) // error
- let과 const는 블록 레벨 스코프로 함수, if 문, for 문, while 문, try/catch 문 등의 모든 코드 블록 {...} 내부에서 선언된 변수는 코드 블록 내에서만 유효하며 외부에서는 참조가 불가능합니다. 즉, 코드 블록 내에서 선언된 변수는 지역 변수로 취급됩니다.
호이스팅
- 호스팅이란 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다.
var로 선언한 변수의 경우 호스팅 시 undefined로 변수를 초기화하고 let 과 const로 선언한 변수의 경우 호스팅 시 변수를 초기화하지 않습니다.
- 또는 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는 것"(실제로 코드가 끌어올려지는 것이 아닌, 자바스크립트 Parser가 함수 실행 전 해당 함수를 한 번 훑는 과정에서 내부적으로 끌어올려 처리하는 것을 뜻하며 실제 메모리에서는 변화가 없음) 뜻하기도 합니다. => 미리 선언문을 실행해둔다고 이해할 수 있습니다.
var , 함수선언문 : 호이스팅이 발생합니다.
/* 변수 호이스팅 */
console.log(abc) // undefined
var a = 5;
console.log(abc) // 5
/* 함수 호이스팅 */
logFunc(); // "hello"
function logFunc() {
console.log("hello");
}
- 변수 abc가 선언되기 전에 참조 되었음에도 에러가 발생하지 않습니다. 이는 코드 실행 전에 자바스크립트 내부에서 미리 변수를 선언하고 undefinde 상태로 초기화를 해두었기 때문입니다. 함수 선언문 또한 동일하게 선언되기 전 호출됨에도 에러가 발생하지 않습니다
let, const, 함수표현식 : 호이스팅이 발생하지만, 다른 방식으로 작동됩니다.
/* 변수 호이스팅 */
console.log(abc); // ReferenceError: abc is not defined
let abc = "hello";
console.log(abc) // "hello"
/* 함수 호이스팅 */
logFunc(); // error
function logFunc() {
console.log("hello");
}
- 변수
abc가 선언되기 전에 참조하니 에러가 발생합니다. 이는 호이스팅이 발생하지 않는 것이 아닌 , 변수의 선언과 초기화 사이에 일시적으로 변수 값을 참조할 수 없는 구간인 TDZ(Temporal Dead Zone)에 빠졋기 때문에 보이는 현상입니다.
- 함수 표현식을 사용하거나
let 또는 const로 변수를 선언하는 경우 , 자바스크립트 내부에서는 코드 실행 전 변수 선언만 해 둘뿐 초기화는 코드 실행 과정에서 변수 선언문을 만났을 때 수행합니다. 그렇기에 호이스팅이 발생하기는 하지만 , 값을 참조할 수 없기 때문에 동작하지 않는 것처럼 보입니다.
| var | let | const |
|---|
| 유효 범위 | Block Scope | Block Scope | Function Scope |
| 값 재할당 | 가능 | 가능 | 불가능 |
| 재선언 | 가능 | 불가능 | 불가능 |
| 호이스팅 | 초기화(undefined) | 초기화 X | 초기화 X |
출처 : 팔만코딩경
출처 : 오픈 투게더