[모던JS] 008. [기본] 변수와 상수(let, var, const, 호이스팅, 명명규칙, 대문자상수)
자바스크립트로 작성된 애플리케이션은 사용자나 서버로부터 입력받은 정보를 처리하는 방식으로 동작한다.
즉 HTML과 CSS로 작성된 문서에 동적인 움직임, 명령, 행동을 발생시키기 위해서 자바스크립트를 이용한다.
(예시)
- 온라인 쇼핑몰 : 장바구니 등의 정보
- 채팅 앱 : 사용자 정보, 메시지 주고 받기
변수 (Variable)
변수의 의미
이름이 붙은 저장소.
데이터를 저장할 때 쓰인다.
예를 들어 쇼핑몰에서는 상품정보나 방문객 등의 정보를 저장할 때 변수를 사용한다.
선언 방법 (let, var)
변수 선언 기본형
변수를 선언하기
let 변수명;
var 변수명;
변수에 데이터를 저장하기
let message;
message = 'Hello';
=이라는 할당 연산자를 사용하여 변수 안에 'Hello'라는 문자열을 저장했다.
let message = 'hello';
위와 같이 한 줄로 작성하는 것이 일반적이다.
let user = 'John', age = 25, message = 'Hello';
let user = 'John',
age = 25,
message = 'Hello';
위와 같이 한 줄에 let을 한 번만 사용하고 여러가지의 변수를 선언할 수 있지만 가독성을 위해 매번 let을 사용해서 한 줄에 한 번만 사용하는 방법이 권장된다.
저장된 데이터에 접근하기
let message;
message = 'Hello';
alert(message);
arlet문을 사용해서 message라는 변수에 저장된 데이터에 접근할 수 있게 되었다.
var를 잘 사용하지 않는 이유
let과 var는 기능이 같다. let이 등장하기 전에는 var가 있었다. 그런데 최근에는 var를 거의 사용하지 않는다. 개발자가 의도하지 않은 에러를 발생시킬 수 있기 때문이다.
var는 블록 스코프가 없다.
var는 전역 스코프이다. 이 말은 var가 함수 내부에서 선언되었다고 하더라도 함수 외부에서 이 변수에 접근이 가능하다는 것이다.
if (true) {
var test = true; // 'let' 대신 'var'를 사용했습니다.
}
alert(test); // true(if 문이 끝났어도 변수에 여전히 접근할 수 있음)
예를 들어 위의 코드를 보면 if문 안에서 var를 통해 test라는 변수를 선언했는데, 보통 함수 안에서 사용하는 변수는 그 함수에서 사용하기 위해 작성하는데 함수 외부에서 다른 코드를 작성하는데 이 변수가 alert로 호출이 된다.
이런 경우를 의도하는 경우는 많이 않으므로 var를 거의 사용하지 않는다. 반대로 let을 사용하면 let은 지역 변수가 되어 함수 외부에서는 이 변수에 대해 접근할 수 없다.
if (true) {
let test = true; // 'let'으로 변수를 선언함
}
alert(test); // Error: test is not defined
특히 반복문에서 이런 문제가 두드러지는데
for (var i = 0; i < 10; i++) {
// ...
}
alert(i); // 10, 반복문이 종료되었지만 'i'는 전역 변수이므로 여전히 접근 가능함.
index를 의미하는 i는 수시로 쓰이는 관용적인 변수명이기 때문에 다른 코드에서도 쓰일 수 있는데 외부에서도 이 변수에 접근이 가능해지기 때문에 i는 더이상 사용할 수 없는 변수명이 되어 버린다.
중복 선언 가능한 문제
var는 변수를 중복 선언할 수 있다.
var user;
var user;
같은 변수를 두 번 선언해도 되기 때문에 나중에 중복 선언된 변수에 접근하고자 하면 가장 마지막에 선언된 변수에만 접근이 가능하다.
var user = "kim";
var user = "jang";
var user = "oh";
console.log(user); // oh
호이스팅 (Hoisting)
var로 선언된 변수는 var 변수가 어디에서 선언됐든 신경쓰지 않고 스크립트를 실행할 때 가장 먼저 읽히고 시작한다.
기본적으로 자바스크립트는 코드가 작성된 순서에 따라 위에서 아래로 코드를 실행시키는데, 이런 호이스팅이라는 현상이 발생하면 개발자가 코드를 어떻게 작성했든 var로 선언한 변수가 먼저 읽히게 되는 것이다. 따라서 예기치 못한 에러를 발생시킬 수 있다.
sayHi = "Hi"; // 값 할당
var sayHi; // 변수 선언
console.log(sayHi); // Hi
변수를 선언하기도 전에 값을 할당했는데 Hi가 정상적으로 출력된다 var sayHi가 호이스팅되어 코드의 최상단으로 이동했기 때문이다.
그런데 변수의 선언에 대해서만 호이스팅이 되는 것이고 값을 할당하는 행위는 호이스팅이 되지 않는다.
var sayHi;
console.log(sayHi);
sayHi = "Hi"; // undefined
위의 코드를 보면 var를 통해 변수를 선언하고 값을 console.log 다음 할당했는데 값의 할당은 호이스팅되지 않기 때문에 console.log가 작동하는 시점에서는 sayHi 변수에 값이 지정되어 있지 않아 undefined가 출력되었다.
값의 변경
값을 할당하는 코드를 작성하는 순간 이전의 값을 지우지 않더라도 값이 변경된다.
let name = "장원영";
name = "안유진"; // 값이 변경됨.
name = "이서"; // 값이 최종적으로 변경됨.
값의 복사
이미 선언한 변수와 할당할 값을 다른 변수에 복사할 수 있다.
let name = "장원영";
let myName;
name = myName;
console.log(myName); // 장원영
변수 명명 규칙
- 문자, 숫자, 기호는 $와 _만 사용 가능
- 첫 글자에는 숫자 사용 불가
- 이미 있는 예약어(키워드, 명령어)는 사용 불가 (예: let let;)
camelCase
여러 문자가 나열된 경우 사용하는 방법이고 규정은 아니지만 가동성을 위한 개발자들의 암묵적인 룰이다. 낙타의 혹같이 생겼다 하여 camelCase라 부른다.
let wonYoung;
바람직한 변수/상수명
- 이름만 보고도 어떤 변수일지 예측이 가능하도록 간결하고 명확해야 함.
- 실제 현업에서는 코드를 새로 작성하는 것보다는 기존에 작성했던 코드를 수정하거나 기능을 확장하는데 더 많은 시간을 들임. 이런 상황에서 변수명이 복잡하면 더 오랜 시간이 걸리게 됨.
let a = "장원영"; // 나만 알 수 있는 변수명은 X
let value = 21; // 무슨 값을 말하는 건지 파악이 어려운 변수명은 X
let userName = "장원영";
let userAge = 21;
위처럼 서술형으로 작성하도록 하고, 최대한 간결히 작성하도록 한다. 방문객을 user라고 할지, visitor라고 할지 그것은 팀원들이 정하는 규칙에 따라 정하도록 한다.
상수 (constant)
let 처럼 변수를 선언하는 예약어이다. 그런데 let과의 차이점은 let은 언제든지 값을 변경할 수 있지만 const는 값을 변경할 수 없다.
const name = "장원영";
name = "안유진";
console.log(name); // Uncaught TypeError: Assignment to constant variable.
// let은 가능하다.
보통 유저의 아이디와 같이 절대로 변해선 안 되는, 변하지 않아야 하는 값에 사용한다. 그리고 let을 사용하고 값을 안 바꿔도 되는 것이지만 const를 사용하는 다른 이유는, 다른 개발자들에게 이 값은 변하면 안 된다는 메시지를 주기 위해 사용할 수도 있다.
대문자 상수
const name과 다르게 const COLOR_RED와 같이 대문자로 변수를 명명하는 경우가 있다. 이것의 의미는 '기억하기 힘든 값'이라는 의미이다.
지키지 않으면 에러가 나는 규정은 아니지만 이것도 camelCase처럼 개발자들이 관습적으로 변수명만 봐도 어떤 변수인지 그 성격을 파악하기 쉽도록 지키는 룰이라고 보면 된다.
const COLOR_RED = "#F00";
const COLOR_GREEN = "#0F0";
const COLOR_BLUE = "#00F";
const COLOR_ORANGE = "#FF7F00";
// 색상을 고르고 싶을 때 별칭을 사용할 수 있게 됨.
let color = COLOR_ORANGE;
alert(color); // #FF7F00
위처럼 16진수 색상코드는 외우기 어렵기 때문에 위와 같이 상수의 값으로 할당해서 사용할 수도 있다.
COLOR_RED와 같은 상수 선언은 코드 연산을 위한 데이터가 아니라 기억하기 힘든 값을 '메모'한다는 느낌이 강한 내용이다.
그리고 여기서 하드 코딩(hardcoding)이라는 개념을 알아야 하는데, const COLOR_RED = "#F00"과 같이 변수나 상수에 값을 직접 할당하는 것을 하드 코딩이라 한다. 일반적으로 하드 코딩은 좋은 습관이 아니다. 왜냐면 나중에 하나의 프로젝트에서 수천줄에 달하는 코딩을 하였을 때 만약 상수의 값이 변경된다면 일일이 찾아서 변경해줘야 하는데 (물론 변경할 일이 절대 없는 위 같은 색상 값 등에 대해서만 하드 코딩하지만 일반적인 경우) 외부에 데이터를 저장해놓고 필요할 때 변수에 값을 할당하는 방식이 훨씬 유연한 방식이다.
즉, 대문자상수는 하드 코딩 그 자체를 의미하는 것이고 다른 개발자들에게 그런 사실을 알리는 역할을 하는 것이다.
'Programing > JavaScript' 카테고리의 다른 글
[모던JS] 010. [기본] alert, prompt, confirm을 이용한 상호작용 (1) | 2024.03.25 |
---|---|
[모던JS] 009. [기본] 자료형(원시 타입, typeof연산자) (0) | 2024.03.25 |
[모던JS] 007. [기본] 엄격 모드(use strict) (0) | 2024.03.25 |
[모던JS] 006. [기본] 코드 구조(문, 주석) (0) | 2024.03.25 |
[모던JS] 005. [기본] Hello, world!(JS 작성법, 내외부 스크립트) (0) | 2024.03.25 |
댓글