변수 선언 방식
자바스크립트의 번수 선언방식에는 여러가지 방식이 존재한다.
그중 가장 대중적인 방식 var, let const는 같은 기능을 하는것 같지만 조금씩 차이점이 존재한다. 이러한 차이점들을 여러가지 관점에서 비교해보았다.
중복 선언
var : 중복 선언 가능
var name = 'javascript'; console.log(name); // javascript var name = 'react'; console.log(name); // react
var로 선언한 변수는 동일한 이름으로 여러번 중복해서 선언이 가능하다. 이 경우 마지막에 할당된 값이 변수에 저장되는것 위의 경우에서 확인할 수 있다.- 중복 선인이 가능하다는 것은 필요할 때 마다 변수를 변경하여 사용할 수 있다는 장점이 될 수 있지만, 이전에 선언해준 변수의 존재를 잊고 값을 재할당 하는 등 실수가 발생할 가능성이 크다. 특히 코드량이 많아졌을 때, 같은 이름의 변수가 여러번 선언되었다면 어디에서 문제가 발생하는지 유지보수 차원에서 어려움을 겪을 확률이 커진다.
- 이러한 경우들로 인해서 이제는 거의 사용되지 않는 방식이 되어버렸다.
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
var와 다르게let은 해당 변수가 이미 선언되었다는 에러 메세지가 출력된다. 중복선언 불가능 name =와 같이 변수 선언 및 초기화 이후 반복해서 재할당 가능하다.vueconst : 중복 선언 불가능, 재할당 불가능
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
let은 변수에 다른 값을 재할당 할 수 있지만,const는 재할당 시 에러 메세지가 출력된다. 재할당 불가능(immutable)- 이처럼
const는 상수(constant)를 뜻하는 단어이기 때문에 한번만 선언 가능하며 값을 변경할 수 없다. 하지만 예외적으로 참조형 배열과 오브젝트의 값을 변경하는것은 가능하다.- 정리하여 말하자면
const는 불변을 의미하는 것과 다르게, 값을 재할당 하는 것만 불가능 하다고 볼 수 있다.스코프 (Scope)
스코프란 유효한 참조 범위를 뜻하며,
var로 선언한 변수와let또는const로 선언한 변수의 스코프는 각각 다르다.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
- 함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조가 불가능하다.
즉, 함수 내부에서 선언한 변수는 지역 변수이고 함수 외부에서 선언한 변수는 모두 전역 변수로 취급이 된다.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
- 함수, if, for, while, try/catch문 등의 모든 코드블록 내부에서 선언된 변수는 코드블록 내에서만 유효하며 코드블록 외부에서는 참조가 불가능하다.
즉, 코드블록 내부에서 선언한 변수는 지역 변수로 취급받는다.호이스팅 (Hoisting)
자바스크립트 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻한다.
알기쉽게 설명하면 변수 선언되지 않은 빈 변수를 코드로 먼저 실행했을 때, 코드가 시작되기 전에 나중에 아랫줄에서 선언된 변수나 함수 선언이 해당 스코프의 최상단으로 끌어올려지는 현상을 말한다.var, 함수선언문 : 호이스팅이 발생함
/* 변수 호이스팅 */ console.log(a); // undefined var a = 5; console.log(a); // 5 /* foo(); // foo function foo() { console.log("foo"); }
var의 호이스팅은var선언과 동시에undefined가 할당되는 초기화가 이루어지기 때문에undefined가 출력이 된다.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"); }
let과const는 선언만 될뿐 초기화가 이루어지지 않는다.
그 이유는let이나const선언시 아직 메모리가 할당되지 않은 TDZ = temporal dead zone에 들어가게 되므로 TDZ에서는 이러한 선언 이전의 변수 사용을 엄격하게 금지하고 있으므로 호이스팅 시 ReferenceError가 발생하게 된다.