변수 선언
자바스크립트에서 변수 선언 방식은, type명으로 선언하는 것이 아닌 아래의 3가지 키워드를 통해 생성할 수 있다.
var | 중복선언 O, 재할당 O |
let | 중복선언 O, 재할당 X |
const | 중복선언 X, 재할당 X |
위의 키워드를 통해, 변수를 선언하고 각 변수의 타입은 변수의 할당 단계(초기화)에서 결정된다.
var 변수 선언
var는 자바스크립트의 초창기부터 있었던 변수 선언 방식으로, 중복 선언과 재할당이 가능하며 마지막에 할당된 값이 변수에 저장된다.
//var 선언
var str = "javascript";
console.log(str); //javascript
//중복선언 O
var str = "hello";
console.log(str); //hello
//재할당 O
var str = "bye";
console.log(str); //bye
예제에서 알 수 있듯이, var 변수는 다른 변수 선언에 비해 자유롭지만, 소스 코드가 복잡해질 경우 기존 선언했던 변수를 잊고 다신 선언하거나 재 할당을 해서 어떤 부분에서 값이 변경되는지 파악하기 힘든 경우가 생긴다.
그렇기 때문에, var 변수는 크게 사용하지 않는 추세이다.
let 변수 선언
let은 중복 선언은 불가능 하지만 재할당은 가능하다.
//let 변수 선언
let str = "javascript";
console.log(str); //javascript
//중복선언 X -> 오류 발생
let str = "hello"; //Uncaught SyntaxError : Identifier 'str' has already been declared
//재할당 O
str = "hello";
console.log(str); //hello
const 변수 선언
const는 constant(상수)를 뜻하는 변수로서, 중복 선언 및 재할당 모두 불가능하다.
//const 변수 선언
const str = "javascript";
console.log(str); //javascript
//중복선언 X -> 오류 발생
const str = "hello"; //Uncaught SyntaxError : Identifier 'str' has already been declared
//재할당 X -> 오류 발생
const = "hello"; //Uncaught TypeError : Assignment to constant variable
하지만, const의 경우 배열과 객체일 때에는 값을 변경하는 것이 가능하다.
//배열
const arr = [1, 2, 3];
arr.push(4);
console.log(arr); //[1, 2, 3, 4]
//객체
const obj = {'apple' : 2, 'orange' : 1};
obj['peach'] = 3;
console.log(obj); //{'apple' : 2, 'orange' : 1, 'peach' : 3}
변수의 범위(scope)
변수의 범위는 변수가 어떤 레벨의 스코프까지 참조하는 것이 유효한지에 대한 것이다. 자바스크립트에서 변수는 다음과 같은 scope를 가진다.
var | 함수 레벨 스코프(function-level scope) |
let / const | 블록 레벨 스코프(block-level scope) |
함수 레벨 스코프
자바에서 변수 var는 함수 레벨 스코프를 가진다. 함수 레벨 스코프는 함수 내에서 선언된 변수는 함수 블록 내외부에 관계없이 함수 내에서라면 어디에서든 유효한 참조 범위를 가지는 스코프이다.
function func() {
if(true) {
var str = "hello";
console.log(str); //hello
}
console.log(str); //hello
}
func()
//함수 내에 선언된 변수는 밖에서는 사용 X
console.log(str); //ReferenceError : str in not defined
블록 레벨 스코프
변수 let, const는 블록 레벨 스코프를 가지는 데, 블록은 중괄호로 둘러싸여진 부분을 한 블록이라 하고 이 블록 내에서 선언된 변수 let, const는 해당 블록 내에서만 동작한다.
function func() {
if(true) {
let str = "hello";
const a = 1;
if(true) {
console.log(str); // hello
}
console.log(a); // 1
}
//block 범위 밖에서는 사용 X
console.log(str) //ReferencedError : str is not defined
}
func()
호이스팅(Hoisting)
자바스크립트에서는 특별한 개념인 호이스팅이 있다. 호이스팅이란 무언가를 들어 올리거나 끌어올리는 것을 뜻하는데 자바스크립트에서는 변수를 끌어올린다.
자바스크립트에서 인터프리터는 변수의 생성을 변수 생성 키워드를 통한 변수 선언 단계와 선언한 변수의 값을 초기화하는 할당 단계로 분할한다.
이 때 변수의 선언 단계를 해당 변수의 스코프(유효 참조 범위) 제일 위로 끌어올려 수행하기 때문에 호이스팅이라고 한다.
var 호이스팅
아래 예제를 보면 변수가 선언되기 전의 str 변수를 console 창에 출력시키는 것을 볼 수 있다.
//선언되기 전의 변수 호출
console.log(str); //undefined
//변수 선언
var str = "javascript";
위의 코드의 동작 과정을 살펴보면 다음과 같다.
- 변수(str) 생성 선언 단계 호이스팅 -> var str = undefined 할당
- console.log(str) : undefined 출력
- 변수(str) 생성 할당 단계 : str <- javascript
변수 선언 단계에서 자바스크립트의 인터프리터가 호이스팅을 한 뒤 해당 변수에 undefined 값을 임의로 할당하기 때문에, 변수 선언 전에도 해당 변수를 사용할 수 있다.
let / const 호이스팅
let / const의 경우에도, 변수 선언 단계에서 호이스팅이 일어나지만 var 변수와의 차이점은 undefined값을 임의로 할당해주지 않는다는 것이다.
그렇기 때문에 let / const 변수의 경우, 실제 할당 단계에서 값이 할당 되기 전까지는 변수를 사용하지 못하기 때문에 아래 예제와 같이 오류가 발생한다.
//선언되기 전의 변수 호출
console.log(str); //Uncaught ReferenceError : Cannot access 'str' before initialization
//변수 선언
let str = "javascript";
let / const 변수를 할당 전까지 사용할 수 없는 비활성 상태를 일시적 데드 존(TDZ : Temporal Dead Zone)이라고 한다.
결론
자바스크립트를 사용하는 개발자들은 변수의 중복선언, 재할당을 최소화하는 것을 권한다. 그렇기 때문에 var 보다는 let / const를 사용하고 그 중에서도 재할당이 필요없는 경우에는 const를 주로 사용한다.
let을 사용하더라도 변수의 scope를 최대한 좁게 만들어서 사용하는 것을 권장한다.
'Programming > 자바스크립트' 카테고리의 다른 글
[자바스크립트] String - 개념 (1) | 2023.10.23 |
---|---|
[자바스크립트] Number (0) | 2023.10.22 |
[자바스크립트] 템플릿 리터럴 (1) | 2023.10.22 |
[자바스크립트] 데이터 타입의 종류 (0) | 2023.10.21 |
[자바스크립트/JavaScript] 연산자 (1) | 2023.10.20 |