[Study] FE/📕 ModernJS_DeepDive Study

[ModernJS_DeepDive] 4장 변수

stop-zero 2023. 6. 8. 23:49
책 제목: 모던 자바스크립트 Deep Dive
저자: 이웅모 저
출판사: 위키북스

모르는 것만 골라볼까, 고민하다가 아는 개념은 빠르게 넘기기로 .... 사실 모르는 게 더 많음
하다 보니까 할당 부분에서 var, let, const 차이를 알고 4장을 보는 것이 더 이해하기 좋을 것 같다는 생각을 했다.
var는 아예 안쓰는데, 이 책에서 예제 설명할 때 var를 사용하여서 일단은 책에 있는 그대로 따라갔다.

4.1 변수란 무엇인가? 왜 필요한가?

아무리 복잡한 애플리케이션이더라도 *동작 방식은 다 똑같다. 

*동작 방식: 데이터 입력받기 > 처리하기 > 결과 출력하기 

 

데이터를 관리하기 위해서 변수는 주요 개념이다. 

10 + 20

사람은 위의 식을 계산하기 위해 아래와 같은 과정으로 결과인 30을 출력한다. 

1) 10, 20, + 의 의미를 알고 있다.
2) 10+20 의 식도 파싱(해석) 가능하다. 

자바스크립트 엔진(=컴퓨터)도 사람과 같은 과정으로 결과를 출력한다. 

사람은 모든 것을 1, 2번을 모두 두뇌에서 수행하지만, 컴퓨터는 연산을 수행하는 CPU와 피연산자(10, 20)를 기억하는 *메모리로 나눠서 수행한다. 

 

*메모리 

- 데이터를 저장하는 메모리 셀의 집합체

- 셀 하나의 크기 : 1바이트 (8비트)

- 컴퓨터는 1바이트 단위로 데이터를 읽거나 저장

- 메모리의 모든 값은 2진수로 저장

 

But, 연산이 끝난 후 CPU가 만들어낸 30의 숫자는 재사용할 수 없다.

재사용을 하기 위해 연산 결과가 저장된 공간에 직접 접근한다면 오류를 발생할 확률이 높다.

만약 운영체제가 사용하고 있는 값을 변경한다면 시스템이 멈추게 된다. 

이를 해결하기 위해서는 변수를 사용하면 된다. 

변수 

- 하나의 값을 저장하기 위한 메모리 공간

- 메모리 공간을 식별하기 위해 붙인 이름(=값의 위치)  

개념 변수 이름 (=result) 변수값 (=30) 할당(=Assignment, 대입, 저장) 참조
의미 메모리를 식별하는 이름  변수에 저장된 값 변수에 값을 저장하는 행위  수에 저장된 값 읽기 

 

4.2 식별자

사람을 이름으로 구별하는 것처럼 값도 식별자로 구별한다.  메모리 공간에 저장되어 있는 값을 구별해 낼 수 있는 것이 식별자이다. 

식별자는 값이 저장되어 있는 메모리 주소를 기억(저장)한다. 

즉 위에 그림에서는 30이 있는 0x066F913을 기억한다. 

변수만 식별자인 것이 아니라, 함수, 클래스 등의 이름 모두 식별자가 될 수 있다. 

 

4.3 변수 선언

변수를 사용하기 위해 var, let, const *키워드를 사용해 선언한다. ES6 이전에는 var 만을 사용하여 선언하였다.

*키워드

- 자바스크립트 코드 동작을 수행할 일종의 명령어

 

var 키워드는 블록 레벨 스코프를 지원하지 않고, 함수 레벨 스코프를 지원한다. 이로 인해 전역 변수가 선언되고 부작용이 발생할 수 있다.. 이런 단점을 보안하기 위해 let과 const 키워드가 도입되었다. 나는 var 키워드를 그냥 없는 취급할 예정이다. 

 

var result; // 변수 선언

변수 선언만 하고 변수 (=result)에는 값을 할당하지 않은 상태이다. 값을 할당하지 않았다고 해서 메모리 공간이 비어있는 것은 아니다. 확보된 메모리 공간에는 자바스크립트 엔진에 의해 undefined 이 할당되어 초기화된다. 

여기서 초기화 단계를 거치지 않으면 이전 사용값(=쓰레기 값, Garbage Value)이 남아있을 수 있다. 

 

자바스크립트 엔진은 실행 컨텍스트를 통해 소스코트를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 관리한다. 

즉, 변수 이름이 등록되는 곳은 실행 컨텍스트이다. 

 

변수뿐만 아니라 모든 식별자는 사용 전에 선언해야 한다. 

선언되지 않은 apple이라는 변수를 선언하였다고, ReferenceError(참조 에러)가 발생했다. 이는 식별자를 통해 값을 참조하려고 했지만, 자바스크립트 엔진이 등록된 식별자를 찾을 수 없을 때 발생하는 에러이다. 

 

4.4 변수 선언의 실행 시점과 변수 호이스팅

변수 호이스팅은 변수 선언문이 코드의 선두로 올려져 동작하는 자바스크립트의 고유의 특징이다. 

자바스크립트 엔진은 코드를 실행하기 앞서, 소스코드 평가 과정을 거치면서 실행을 위한 준비를 한다. 엔진은 소스코드에서 선언문을 먼저 실행한다. 이 과정이 끝나면 소스 코드에서 선언문을 제외하고 순차적으로 실행한다. 

=> 엔진은 변수 선언이 어디 있든 가장 먼저 실행하여 ReferenceError가 발생하지 않는다. 

 

+ const를 사용하게 되면 SyntaxError가 발생하게 된다. var과 let이랑은 달리 const 선언에서는 반드시 값을 정의해야 하기 때문이다. 자바스크립트에서 상수는 const 키워드를 사용해 선언되는데 상수는 이니셜라이저(=선언과 동시에 초기화)가 필요하다. 그냥 상수를 선언할 목적이 아니라면 const를 사용하지 않는 것이 좋다. 

 

4.5 값의 할당

var result; // 변수 선언
result = 30;	// 값의 할당

var result = 30;	// 변수 선언과 값의 할당
변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다. 

 

이게 뭔소리냐, (긴 글 읽기 싫은 애 -> 그게 바로 나...)

[변수 선언] , [값의 할당] 두 개의 실행시점이 다르다는 것이다. 

변수 선언은 런타임 이전에 실행되고, 값의 할당은 순차적으로 실행된다. 

 

4.6 값의 재할당

값이 이미 정해진 변수에 새로운 값을 할당하는 것을 의미한다. 

이전 값인 30은 불필요한 값으로 가비지 콜렉터(Garbage Collector)에 의해 메모리에서 자동 해제된다. 단, 언제 해제될지는 예측할 수 없다. 

+ 여기서 또 const는 상수를 표현하기에 재할당 할 수 없다. 

 

4.7 식별자 네이밍 규칙

사실상 프로젝트를 하다 보면 이름 짓는 것이 가장 어려운 일이다. 변수에 대한 이름을 고민할 때 챗 gpt에게 물어본다면 잘 지어주긴 하더라;) 다른 프로그래밍 언어를 이미 접해봤다면 익숙한 부분일 것이다. 나도 점점 이름에 대한 규칙은 가장 많이 쓰는 것만 계속 쓰기에 모든 것을 기억해두지 않는 것 같다. 

식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러기호($)를 포함할 수 있다. 단 숫자로 시작하는 것은 안되고 문자, 언더스코어(_), 달러기호($)로 시작해야 한다. 예약어도 식별자로 사용할 수 없다.

// 카멜 케이스(camelCase)
var main;

// 스네이크 케이스(snake_case)
var side_bar;

// 파스칼 케이스(PascalCase)
var SideBar;

// 헝가리언 케이스(typeHungarianCase)
var strFirstMan;	// type + identifier
var $elem = document.getElementById("myId");	// Dom 노드
var observable$ = fromEvent(document, "click");	// RxJS 옵저버블