변수 (Variable)
하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름
- 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘
- 메모리 공간에 저장된 값을 다시 읽어 들여 재사용할 수 있도록 값이 저장된 메모리 공간에 상징적인 이름을 붙인 것
✨ 변수명: 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름
✨ 변수값: 변수에 저장된 값
✨ 할당: 변수에 값을 저장하는 것 (a.k.a 대입, 저장)
✨ 참조: 변수에 저장된 값을 읽어 들이는 것
식별자 (Identifier)
어떤 값을 구별해서 식별할 수 있는 고유한 이름
- 식별자는 값이 아닌 메모리 주소를 기억한다. 즉, 메모리 주소에 붙인 이름이다.
- 변수, 함수, 클래스 등의 이름은 모두 식별자이다.
- 메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름은 모두 식별자라고 한다.
변수 선언 (Variable Declaration)
변수를 생성하는 것
- 값을 저장하기 위한 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해서 값을 저장할 수 있게 준비하는 것이다.
- 메모리 해제 전까지는 할당된 메모리 공간은 사용할 수 없도록 보호되므로 안전하게 사용할 수 있다.
- 변수 선언시 var, let, const 키워드를 사용한다.
var score; //변수 선언(변수 선언문)
- 위의 코드는 변수 이름을 등록하고 저장할 메모리 공간을 확보한다.
- 변수에 값을 할당하기 전까지 확보된 메모리 공간에는 자바스크립트 엔진에 의해 undefined 라는 원시 타입의 값(Primitive Value)이 자동으로 할당되어 초기화된다.
✨ var : 선언 단계와 초기화 단계가 동시에 진행된다.
1. 선언 단계 : 변수명 score 등록
2. 초기화 단계: undefined 할당
- 변수를 초기화하지 않을 경우, 쓰레기 값이 할당되는데 var는 암묵적인 초기화를 수행하므로 이런 위험으로부터 안전하다.
- 선언하지 않은 식별자에 접근하면 참조 에러(ReferenceError)가 발생한다.
- 참조 에러 (ReferenceError) : 식별자를 통해 값을 참조하려 했지만 자바스크립트 엔진이 등록된 식별자를 찾을 수 없을 때 발생.
변수 선언의 실행 시점과 변수 호이스팅
변수 호이스팅 (Variable Hoisting)
변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징
- 자바스크립트는 소스코드를 실행하기에 앞서 소스코드 평가 과정에서 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행한다.
- 소스코드의 평가 과정이 끝나면 모든 선언문을 제외한 나머지 소스코드를 한 줄씩 순차적으로 실행한다.
- 즉, 소스코드 내 어디에서 변수를 선언하든 다른 코드보다 먼저 실행된다. (== 어디서든 변수를 참조할 수 있다.)
- 아래 예시 코드를 살펴보자. 변수 선언 전에 score 변수를 사용하여 참조에러가 발생할 것 같지만 에러 없이 undefined가 정상적으로 출력된다.
console.log(score); // undefined
var score; // 변수 선언문
✨WHY? 변수 선언은 런타임이 아니라 그 이전 단계에서 먼저 실행되기 때문이다.
✨런타임: 소스코드가 한 줄씩 순차적으로 실행되는 시점. (변수의 값이 이때 할당됨)
- 변수 선언뿐 아니라 var, let, const, function, function*, class 키워드를 사용하여 선언하는 모든 식별자(변수, 함수, 클래스)는 호이스팅 된다.
- 즉, 모든 선언문은 런타임 이전 단계에서 먼저 실행된다.
값의 할당 (Assignment)
- 변수에 값을 할당할 때에는 할당 연산자 " = "를 사용한다.
- 할당 연산자는 우변의 값을 좌변의 변수에 할당한다.
var score; // 변수 선언
score = 80; // 값의 할당
// 아래와 같이 한 줄로도 표현할 수 있다.
var score = 80;
🔥주의할 점: 변수 선언과 값 할당 시점이 다르다.
✨ 변수 선언 - 런타임 이전에 먼저 실행된다.
✨ 값의 할당 - 런타임에 실행된다.
console.log(score); // undefined
var score; // 1) 변수 선언 - 런타임 이전에 실행
score = 80; // 2) 값의 할당 - 런타임에 실행
console.log(score); // 80
- 위 코드의 경우 score 변수에 값을 할당하는 시점에는 이미 변수 선언이 완료된 상태이며 이미 undefined로 초기화되어 있다.
- 따라서 score 변수에 값을 할당하면 score 변수의 값은 undefined에서 새롭게 할당한 숫자 값 80으로 변경(재할당)된다.
- 변수 선언과 값 할당을 한 문장으로 단축 표현해도 자바스크립트 엔진은 변수의 선언과 값의 할당을 2개의 문으로 나누어 각각 실행한다. 따라서 변수에 undefined가 할당되어 초기화되는 것에는 변함이 없다.
- 변수에 값을 할당할 때에는 이전 값 undefined가 저장되어 있던 메모리 공간을 지우고 그 메모리 공간에 할당 값 80을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그곳에 할당 값 80을 저장한다.
값의 재할당
이미 값이 할당되어 있는 변수에 새로운 값을 또다시 할당하는 것
- 현재 변수에 저장된 값을 버리고 새로운 값을 저장한다.
var score = 80; // 변수 선언과 값의 할당
score = 90; // 값의 재할당
- var 키워드로 선언된 변수는 값의 재할당이 가능하다.
- var로 선언된 변수는 애초에 undefined로 초기화되기 때문에 엄밀히 따지자면 변수에 처음으로 값을 지정하여 할당하는 것도 재할당에 해당된다.
- 재할당은 처음 값 할당과 마찬가지로 원래 값이 있었던 공간에 새로운 값을 할당하는 것이 아니라 새로운 메모리 공간을 확보하고 새롭게 확보된 메모리 셀에 새로운 값 저장한다.
- 이 경우, 사용하지 않는 이전 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제된다.
- 쓰레기 값들이 메모리에서 언제 해제될지는 알 수 없다. ※ 예측불가 ※
✨ 가비지콜렉터(garbage collector) : 어플리케이션이 할당한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 해제하는 기능을 말한다. 더 이상 사용되지 않는 메모리란 어떤 식별자도 참조하지 않는 메모리 공간을 의미하며 이러한 메모리 공간을 해제하여 메모리 누수를 방지한다.
- 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없는 것을 상수라고 한다.
- 상수는 한번 정해지면 변하지 않는 값, 즉, 단 한 번만 값을 할당할 수 있는 변수이다.
✨ const 키워드를 사용하면 상수를 표현할 수 있다.
✨ 단 한 번만 할당할 수 있는 변수를 선언하며 재할당이 금지된다.
✨ 그러나 const 키워드를 사용했다고 해서 반드시 상수인 것은 아니다.
식별자 네이밍 규칙
- 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
- 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.
- 예약어는 식별자로 사용할 수 없다.
예약어 (Reserved Word)
예약어는 프로그래밍 언어에서 사용되고 있거나 사용될 예정인 단어를 말한다. 자바스크립트의 예약어는 다음과 같다.
await | break | case | catch | class | const |
continue | debugger | default | delete | do | else |
enum | export | extends | false | finally | for |
function | if | implements | import | in | instanceof |
interface | let | new | null | package | private |
protected | public | return | super | static | switch |
this | throw | true | try | typeof | var |
void | while | with | yield |
- 파란색 예약어는 식별자로 사용할 수 있으나 strict mode에서는 사용할 수 없는 단어이다.
네이밍 컨벤션 (Naming Convention)
하나 이상의 영어 단어로 구성된 식별자를 만들 때 가독성 좋게 단어를 한눈에 구분하기 위해 규정한 명명 규칙
// 카멜 케이스 (camelCase)
var firstName;
// 스네이크 케이스 (snake_case)
var first_name;
// 파스칼 케이스 (PascalCase)
var FirstName;
// 헝가리언 케이스 (typeHungarianCase)
var strFirstName; // type + identifier
var $elem = document.getElementByID('myID'); // DOM 노드
var observable$ = fromEvent(document, 'click'); // RxJS 옵저버블
🔥일반적인 사용 관례
✨ 카멜 케이스 - 변수명, 함수명
✨ 파스칼 케이스 - 생성자 함수명, 클래스명
- ECMAScript 사양에 정의되어 있는 객체와 함수들도 카멜 케이스와 파스칼 케이스를 사용하고 있다. 따라서 코드 전체의 가독성을 높이려면 카멜 케이스와 파스칼 케이스를 따르는 것이 유리하다.
'Web > JS' 카테고리의 다른 글
[JS] 모던 자바스크립트 Deep Dive - 09. 타입 변환과 단축 평가 (0) | 2024.03.29 |
---|---|
[JS] 모던 자바스크립트 Deep Dive - 08. 제어문 (1) | 2024.03.23 |
[JS] 모던 자바스크립트 Deep Dive - 07. 연산자 (1) | 2024.03.22 |
[JS] 모던 자바스크립트 Deep Dive - 06. 데이터 타입 (2) | 2024.03.16 |
[JS] 모던 자바스크립트 Deep Dive - 05. 표현식과 문 (0) | 2024.03.16 |