자바스크립트는 동적 언어로써 런타임에 타입이 결정되는 언어이다. 따라서, 변수를 선언할 때, C나 Java에서처럼 int, float, bool, String 과 같은 자료형을 따로 표기해주지 않는다.
단지 let, const, var 문 만이 있을 뿐이다. (var은 ES6 이후로 쓰지 않을것을 권장하는데 밑에서 자세히 설명하겠다.)
변수 선언 방법 #1 let
{
let number = 1;
let float = 1.4;
let name = 'Kai';
let nothing = null;
let ReadAble = true;
console.log("num=" + number + ", boolean=" + ReadAble);
// num=1, boolean=true
}
console.log(`string=${name}`); //변수가 선언된 블록 밖에서 변수를 사용할 수 없다.
ES6에 추가된 문법으로, 가장 일반적인 변수 선언 방법은 let을 사용하는 것이다. let "변수명"을 통해 변수를 선언 할 수 있으며, 별도의 타입을 따로 지정하지 않는다. 따라서 '겉으로 보기엔 심플하고 좋다'라고 생각할수도 있겠지만 변수의 타입을 쉽게 파악할 수 없어 오히려 가독성이 떨어지고 불편한 경우가 발생한다.
(이를 보완하기위해 JS기반의 TypeScript 언어가 등장했다. )
- 또한, let으로 선언된 변수는 변수가 선언된 블록, 표현식에서만 유효하므로, 변수가 선언된 블록 바깥에서는 사용할 수 없다.
let name = "kai";
let name = "rachel";
// let 중복 선언시 SyntaxError 발생
let age = 25;
age = 30;
// let 변수에 값의 재할당은 가능.
- 위 예시에서와 같이 기존에 존재하는 변수명으로 중복해서 선언할 경우 SyntaxError가 발생한다.
- 하지만 선언된 변수에 할당된 값을 바꾸어주는것은 가능하다.
변수 선언 방법 #2 const
const는 let과 마찬가지로 ES6에 추가된 문법으로, Const 의 가장 큰 특징은 변수 선언 후 값의 재할당이 불가능하다는 점이다.
const MAX = 30;
const MIN = 10;
MAX = 25;
MIN = 10;
// TypeError 발생
const AGAIN = "First";
const AGAIN = "Second";
// SyntaxError 발생
- 위에 예시에서처럼 const로 선언된 변수 MAX에 새로운 값을 할당하려하면 TypeError가 발생한다. 즉, const로 변수를 선언하면 이후에 값을 변경하는것이 불가능하다.
- const로 선언된 변수 또한, 변수가 선언된 블록, 표현식에서만 유효하므로, 변수가 선언된 블록 바깥에서는 사용할 수 없다.
- let과 같이 중복 선언도 불가능하다.
그렇다면 이런 제약이 없는 let을 사용하면 되는것 아니냐? 라고 할 수 있다. 하지만 꼭 그렇지만은 않다.
코딩을 하다보면, 한 번 선언된 변수가 프로그램이 끝날때 까지 한번도 다른 값으로 재할당되지 않거나, 절대로 바뀌지 말아야 할 변수가 사용 될 수 있다. (마치 수학에서 원주율처럼 절대 변하지 않는 값 말이다.) 이 때, const를 사용하여 변수를 선언한다면 그 값이 실수로 다른 값으로 변경이 된다거나 하는 문제가 발생하지 않는다. 또한, 다른 개발자가 코드를 봤을 때에도 "저 const MAX 라는 값은 변하지 않겠구나"하고 변수의 의미를 유추할 수 있다.
결과적으로, let, const의 적절한 사용을 통해 코드의 안정성을 높일수가 있다.
변수 선언 방법 #3 var
앞선 let과 const문의 설명에서 "ES6 이후에 추가된 문법"이라는 말을 했다. 그렇다면 그 이전에는 어떻게 변수를 선언했을까? 그 주인공이 바로 'var'이다.
ES6 이전에는 변수의 선언방법이 오직 'var'밖에 없었다. 그래서 오래된 JS 코드나 강의를 보면, var문으로 변수를 선언한 경우가 많다. 하지만, 최근 강의나 책에서 보면 더이상 var을 사용하지 말라고 하는 경우가 대부분이다. 왜 그럴까?
var을 통한 변수 선언및 사용은 코드의 안정성을 떨어트린다. 그 이유는 크게 세가지로 다음과 같다.
- 중복 선언 가능
- 변수의 유효범위
- 호이스팅(Hoisting)
- 중복 선언 -
var로 선언한 변수는 중복해서 선언 및 초기화가 가능하다.
var adress = "Bucheon";
var adress = "Seoul";
console.log(adress);
// Seoul
만약 기존에 선언해둔 변수의 존재를 잊고 똑같은 변수명으로 선언 할 경우, let과 const에서는 SyntaxError가 발생하여 이를 막아준다.
하지만, var은 기존에 저장된 값을 지우고 마지막에 할당된 값을 저장해버린다. 이로 인해 컴파일 에러는 발생하지 않지만 전혀 기대하지 못했던 값이 나온다거나 하는 문제가 생길 수 있다.
- 변수의 유효 범위 -
let과 const로 선언된 변수는 블록 범위 내에서 유효한 변수이다. 하지만 var은 해당 변수가 선언된 함수 범위 내에서 유효하다.
function greetingUser(){
var user = "kai"
let name = "Tom"
}
console.log(Tom); // 컴파일 Error 발생
console.log(user); // 컴파일 Error 발생
위의 예시에서 두 줄의 console.log()는 둘 다 에러가 발생한다. let은 블록 { } 범위 내에서 유효하고 var은 함수 범위 내에서 유효하기 때문이다.
다음 예시를 보자.
if (true) {
var friend = "Rachel";
let bestFriend = "LoL";
}
console.log(bestFriend); // 컴파일 Error 발생
console.log(friend); // "Rachel"
if문 블록 { } 안에 var변수와 let 변수가 선언되어있다. 콘솔에 let 변수를 찍어보면 Error가 발생한다. 하지만 var로 선언된 변수는 블록 { }이 아닌 함수를 기준으로 유효 범위를 결정하기 때문에, if 문 밖에서 변수를 참조하는 것이 가능하다.
블록 밖에서 특정 블록 안에 선언된 불필요한 변수들까지 참조가 가능하게 되어 이 역시 코드의 안정성을 떨어트린다.
- 호이스팅 -
호이스팅이란, 변수나 함수가 어디에 선언되어 있던 해당 선언부가 코드의 최상단으로 끌어올려지는 것을 말한다. 이에대한 자세한 설명은 다음 링크에서 확인 할 수 있다.
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
let, const, var 변수 모두 호이스팅이 발생한다. 하지만 var의 호이스팅은 방식이 조금 다르다.
console.log(name); // undefined
console.log(number); // 컴파일 Error 발생
var name = "kiwoo";
let number = 25;
위의 예시를 보자. 콘솔에 var과 let의 변수를 선언되기 전에 찍어보았다.
일반적으로, "변수를 선언하기 전에 참조했으니 1, 2번째 코드가 오류가 나겠네" 라고 생각 할 것이다.
하지만 에러는 두번째 console.log에서만 발생한다.
두번째 줄 코드를 지운 후 컴파일 해보자.
일단, 컴파일 에러가 발생하지 않고 console에 undefine이라는 값이 찍히는 것을 볼 수 있다. 이는 var의 호이스팅 방식때문에 그런것인데
- var은 컴파일 시 변수를 어디에 선언했건 상관없이 선언부를 코드의 최상단으로 끌어올려 undefined 로 초기화 해버린다.
- 반면, let이나 const는 선언부가 코드의 최상단으로 끌어올려지긴 하지만 따로 초기화 하지 않는다.
따라서, var 변수 선언 전에 해당 변수를 참조해도 에러가 발생하지 않는 것이다.
결론
let, const, var의 주요 특징들을 정리해보자면 다음과 같다.
var | const | let | |
재할당 | O | X | O |
중복 선언 | O | X | X |
호이스팅 | 코드 최상단에서 undefined로 초기화 |
코드 최상단에서 따로 초기화 하지 않음 |
코드 최상단에서 따로 초기화 하지 않음 |
변수 유효범위 | 함수(function) 범위 | 블록 { } | 블록 { } |
결론은 다음과 같다.
- const를 default로 사용하되,
- 가끔 let을 사용하고
- var은 절대로 사용하지 않는다.
잘못된 부분에 대한 지적이나 개선점 등은 댓글로 남겨주시면 감사하겠습니다.