1976s
이 블로그는 웹 개발, 프로그래밍, IT 활용법을 다루며, 실용적인 팁과 정보를 제공합니다.
-
recentPost
-
popularPost
-
Archive
-
recentComment
공부/Javascript
자바스크립트 변수 var, let, const
자바스크립트를 하면서 변수에 대하여 깊게 생각해 보지 않고 사용한 것 같습니다. 그리고 많이들 var
로 변수를 선언하지 말고 const
와 let
을 사용하라고 합니다. 왜 var
를 지양하는지 변수를 정리하면서 알아봅시다.
0️⃣ 변수(Variables) 란?
변수(variable)는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름입니다. 간단히 말해, 변수는 값의 위치를 알려주는 상징적인 이름입니다.
let myNum = 10;
변수명 myNum은 변수 값이 아닌 메모리 주소를 기억하고, 변수명을 사용하면 JS엔진(자바스크립트 엔진, 이하 JS엔진)이 변수명과 매핑된 메모리 주소를 통해 저장된 값(10)을 반환합니다.
이처럼,
변수에 값을 저장하는 것을 할당(assignment),
저장된 값을 읽어 들이는 것을 참조(reference),
변수명을 JS엔진에 알리는 것을 선언(declaration)이라 합니다.
이 중에 먼저 변수 선언부터 알아봅시다.
1️⃣ 변수선언
자바스크립트에서 변수 선언은 선언 → 초기화 단계를 거쳐 수행됩니다.
- 선언 단계 : 변수 이름을 등록해 JS엔진에 변수의 존재를 알린다
- 초기화 단계 : 값을 저장하기 위한 메모리 공간 확보하고 암묵적으로 'undefined한정되지 않은, 확실하지 않은'를 할당해 초기화한다.
var 변수명 = 값; // 변수 선언과 할당
var 변수명; // 변수 선언
변수명 = 값; // 값의 할당
// 변수를 여러개 나열해서 한꺼번에 선언
var 변수명1, 변수명2, 변수명3, ... ;
// 변수를 여러개 나열해서 한꺼번에 선언 그리고 할당
var 변수명1 = 값1, 변수명2, 변수명3 = 값3, ... ;
위의 선언 시 쓰인 var
은 키워드로 먼저 알아보겠습니다.
키워드
자바스크립트에서는 변수를 만들 때 앞에 자료형을 적지 않고 var
, let
, const
키워드를 사용할 수 있습니다. ES6부터는 주로 let
과 const
를 사용을 권장하고 있습니다.
- var 🚫
재할당 | 재선언 | |
var |
⭕ | ⭕ |
let |
⭕ | ❌ |
const |
❌ | ❌ |
ES5까지는 유일하게 변수를 선언하는 키워드였습니다. 선언 시 할당한 값은 재할당이 가능하며, 재할당 시 var 키워드는 필요하지 않습니다. 지금은 거의 사용하지 않는데, 현재 let과 const로 대체된 이유는 중복 선언 허용과 호이스팅(Hoisting), 함수 레벨 스코프(Function-Level Scope) 때문입니다.
첫번째. 중복 선언 허용
// 변수의 중복 선언
var intNumber = 10;
var intNumber = 40;
console.log(intNumber); // 40
위와 같이 한 번 선언한 변수를 var
키워드를 붙여 다시 선언했는데도 구문오류SyntaxError 없이 동작합니다.
중복 선언이 문제가 되는 이유는 간단한 프로그램에서는 편리할 수 있겠으나 코드량이 많아진다면 어디에서 어떻게 사용될지도 파악하기 힘들뿐더러 내가 원하던 값이 아닌 다른 값이 들어가 있는 경우가 발생할 수도 있습니다. 이럴 때에는 찾기가 쉽지 않습니다.
두번째. 호이스팅 (Hoisting)
자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위의 최상단에 선언합니다. 즉, 함수 내에서 아래쪽에 존재하는 내용 중 필요한 변수/함수들을 끌어올리는 것입니다. 이때 할당은 끌어올리지 않습니다.
적용 대상 : var, function
console.log(a); // undefined (에러가 아님)
var a = 40;
변수는 선언되었지만 값이 아직 할당되지 않았다는 뜻에서 undefined 으로 출력됩니다. 참조에러Uncaught ReferenceError: square is not defined at <anonymous>가 나지 않습니다. 이 또한 의도치 않은 실수나 예측을 벗어날 수 있기 때문에 이런 이유들로 var는 더 이상 변수를 선언하는데 권장되지 않습니다.
세번째. 함수 레벨 스코프(Function-Level Scope)
스코프를 한마디로 정의하자면 '변수가 영향을 미치는 범위' 혹은 '변수가 유효한 범위'라고 할 수 있습니다.
자바스크립트에선 스코프는 2가지 타입이 있습니다. 바로 global(전역)과 local(지역) 인데요.
- 전역 스코프(Global Scope)는 말 그대로 전역에 선언되어 있어 어느 곳에서든지 해당 변수에 접근할 수 있다
- 지역 스코프(Local Scope)는 해당 지역에서만 접근할 수 있어 지역을 벗어난 곳에선 접근할 수 없다는 의미.
자바스크립트에서 함수를 선언하면 함수를 선언할 때마다 새로운 스코프를 생성하게 됩니다. 그러므로 함수 몸체에 선언한 변수는 해당 함수 몸체 안에서만 접근할 수 있는데요. 이걸 함수-레벨 스코프(function-level scoped)라고 합니다. 함수 레벨 스코프가 바로 지역 스코프의 예라고 할 수 있습니다.
우선 함수-레벨 스코프 (Function-Level Scope)와 블록-레벨 스코프 (Block-Level Scope)가 무엇인지 알아봅시다.
예로,
function colorName() {
if (true) {
var color = 'red';
}
console.log(color); // red
}
colorName();
위의 소스에서 만약 var color
가 블록 레벨 스코프였다면, color
는 if
문이 끝날 때 파괴되고 console.log
에서 잘못된 참조로 에러가 발생할 것입니다. 그렇지만 color
는 함수 레벨 스코프이기 때문에 foo
함수 내부 어디에서든 에러 발생 없이 참조할 수 있다.
같은 소스에 블록 레벨 스코프로 즉 var을 let로 하였다면,
위의 코드에서 조건문을 포함한 모든 실행 블록을 스코프로 간주하기 때문에 color을 참조할 수 없게 된다. 즉
- var : 함수 레벨 스코프는 함수(function) 내에서 접근할 수 있고,
- let, const : 블록 레벨 스코프는 중괄호{}내에서 접근할 수 있다는 것입니다.
그러면 왜 var은 함수 레벨 스코프로 사용을 권장하지 않는가?
var sum = 0;
for (var i = 0; i <= 10; i++) {
sum += i;
}
console.log(sum);
console.log(i);
위 코드에서 변수 i
의 값은 for
루프가 끝난 다음에도 유지가 됩니다.(11) 왜냐하면 위에 설명드린 것처럼 var
로 선언한 변수는 if
나 for
와 같은 블록-레벨 아닌 함수-레벨에서 범위가 정해지기 때문입니다. 즉, for
문 안에서 var
로 선언한 변수도 블록을 벗어나서도 유효하게 됩니다.
결론적으로 var
를 사용하여 변수를 선언하면, 변수 Hosting과 함수 스코프, 중복 선언도 고려하면서 코딩을 해야 합니다. 따라서 var
를 사용하면 전반적으로 코드가 어떻게 작동할지 예상하기 어려운 상황이 발생할 수 있습니다.
- let 🆗
재할당 | 재선언 | |
var |
⭕ | ⭕ |
let |
⭕ | ❌ |
const |
❌ | ❌ |
let z;
console.log(z); // undefined
z = 1;
console.log(z); // 1
z = 2;
console.log(z); // 2
let
키워드는 var
와 같이 값의 재할당이 가능하지만, 중복 선언과 호이스팅이 발생하지 않는 변수 선언 키워드이다. 값을 할당하지 않고 변수를 먼저 선언한 뒤 나중에 값을 재할당할 수 있다.
- const 🆗
상수(constant)의 약자입니다.
재할당 | 재선언 | |
var |
⭕ | ⭕ |
let |
⭕ | ❌ |
const |
❌ | ❌ |
const a = 'java';
a = 'javascript';
// Uncaught TypeError: Assignment to constant variable.
위 소스는 같은 const로 선언된 변수에 재 할당을 해 본 결과 타입오류Uncaught TypeError: Assignment to constant variable.가 납니다. 이처럼 const
키워드는 값이 불변하는 변수(상수)에 사용됩니다. const
의 값은 선언할 때만 할당이 가능하며, 재할당이 불가능합니다. 하지만 const 변수도 예외는 있습니다. 바로 선언한 값의 타입이 참조형 타입(reference value)인 경우입니다.
const myName = { first: 'Sam', last: 'Kim' };
myName.first = 'Park';
console.log(myName); // {first: 'Park', last: 'Kim'}
문자, 숫자, 불리언(Boolean)과 같은 원시형(Primitive type) 데이터는 변하지 않는 반면 배열, 객체와 같은 참조형 데이터의 값은 const 변수에 할당되어도 프로퍼티에 접근하여 값을 바꿀 수 있습니다. 이는 참조 타입의 특징에 기인한 현상으로, 참조 타입은 데이터 그 자체를 저장하지 않고, 데이터가 있는 주소값(address)을 담고 있기 때문에 주소값은 불변하지만 참조하는 데이터는 바뀔 수 있는 것입니다.
2️⃣ 변수명
변수명 작성 규칙
- 문자와 숫자, 특수문자 '$ _' 만 사용
- 첫 글자가 숫자가 될 수 없다.
- 공백을 사용할 수 없습니다.
- 대/소문자 구분합니다.
- 한글 사용이 불가능합니다.
- 예약어는 변수명으로 사용할 수 없습니다.
사용할 변수명이 사용 불가인지는 JavaScript variable name validator 를 통해 알아볼 수도 있습니다.
abstract, await, arguments, boolean, break, byte, case, catch, char, class, const, continue, debugger, default, delete, do, double, else, enum, eval, export, extends, false, final, finally, float, for, function, goto, if, implements, import, in, instanceof, int, interface, let, long, native, new, null, package, private, protected, public, return, short, static, super, switch, synchronized, this, throw, throws, transient, true, try, typeof, var, void, volatile, while, with, yield
변수명 표기법
변수명의 표기법은 규칙이 아닙니다. 하지만 변수명을 잘 작성하면 가독성과 나중 수정에 유리하기 때문에 몇 가지 통용되는 표시법이 있습니다. 이를 소개합니다.
구분 | 예제 | 설명 |
상수명 표기법 | USER_NAME |
모든 단어는 대문자로 표기하되 단어와 단어사이를 언더바로 표기 |
카멜 표기법 | userName |
모든 단어는 소문자로 표기하되 단어와 단어 사이 조합 시 첫 단어는 대문자 |
파스칼 표기법 | UserName |
모든 단어는 소문자로 표기하되 모든 단어의 처음 스펠링은 대문자 |
스네이크 표기법 | user_name |
모든 단어는 소문자로 표기하되 단어와 단어사이를 언더바로 표기 |
헝가리안 표기법 | strUserName |
카멜표기법과 유사하지만 변수명(식별자) 앞에 형에 관련된 단어 포함 |
위 예시는 일반적인 규칙이며, 특정 컨벤션(Convention)이 있다면 그것을 따르면 됩니다.
3️⃣ 참조
4️⃣ 마무리
var
을 권장하지 않는 것은 알고는 있지만 그렇다고 왜 그런지는 사실 몰랐었습니다. 이번에 공부하면서 여러 가지를 알게 되었네요. 예전 라디오에서 듣던 자바스크립트가 어떻게 만들어졌는지 듣긴 했지만 이렇게 공부하면서 다시 한번 알게 된 것 같습니다. 다음에 시간 되면 자바스크립트에 대해서도 한번 써 보렵니다. ^^
아무튼 이번에 var
에 대하여 알고 왜 지향하는지도 알게 된 시간이었습니다.
수정사항 있으시면 댓글 부탁드립니다.