4장 변수
5장 표현식과 문
6장 데이터 타입
7장 연산자
8장 제어문
9장 타입 변환과 단축 평가
- 옵셔널 체이닝 연산자 ?.
: 좌항의 피연산자가 null 또는 undefined인 경우, undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.
좌항 피연산자가 falsy 값이라도 null 또는 undefined가 아니면 우항의 참조를 이어간다.

- null 병합 연산자 ??
: 좌항의 피연산자가 null 또는 undefinded 인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다.
변수에 기본값을 설정할 때 유용하다.

10장 객체 리터럴
11장 원시 값과 객체의 비교
- 원시 타입의 값
: 변경 불가능한 값으로, 변수에 할당하면 실제 값이 저장된다.
원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달된다. (값에 의한 전달, pass by value)
- 객체 타입의 값
: 변경 가능한 값으로, 변수에 할당하면 참조 값이 저장된다.
객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. (참조에 의한 전달, pass by reference)

12장 함수
변수는 선언(declaration), 함수는 정의(definition)
자바스크립트 엔진은 생성된 함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고, 거기에 함수 객체를 할당한다.
즉, 함수의 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출하는 것을 말한다.
함수 선언문의 경우, 함수 호이스팅이 발생하기 때문에 함수 선언문 이전에 참조가 가능하다.
함수 표현식의 경우, 변수 호이스팅이 발생하기 때문에 런타임 이전에 undefined가 할당된 변수로 인해 함수의 참조가 불가능하다.
13장 스코프
자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색한다.

- 렉시컬 스코프
: 함수를 어디서 정의 했는지에 따라 함수의 상위 스코프가 결정된다.

14장 전역 변수의 문제점
- 지역 변수의 생명 주기
: 메모리 공간이 확보된 시점부터 메모리 공간이 해제되어 가용 메모리 풀에 반환되는 시점까지 존재한다.
<스코프 단위로 동작하는 호이스팅 예시>
foo의 경우, 변수 x에 대해 호이스팅이 발생해, 런타임 이후에 값이 할당되기 전 undefined 값을 갖는다. 따라서, foo 를 실행하면 함수 블록 스코프 내에서의 undefined 값이 출력된다.

- 전역 변수의 생명 주기
: 브라우저 환경에서 전역 객체는 window 이므로, 브라우저 환경에서 var 키워드로 선언한 전역 변수는 전역 객체 window의 프로퍼티다.
즉, 전역 변수의 생명 주기는 전역 객체의 생명 주기와 일치한다.
- 전역 변수의 문제점
- 유효 범위가 커지기 때문에 코드의 가독성이 나빠지고, 의도치 않은 상태 변경이 발생할 수 있다.
- 생명 주기가 길기 때문에 리소스를 오랜 기간 소비한다.
- 검색 속도가 가장 느리다. (하위 스코프부터 전역 스코프로의 검색이 진행되기 때문이다.)
- 파일이 분리되어 있어도 하나의 전역 스코프를 공유하는 자바스크립트의 문제로 인해 예상치 못한 결과를 일으킬 수 있다.
- 전역 변수의 사용을 억제하는 방법
- 즉시 실행 함수
- 네임스페이스 객체
- 모듈 패턴
- ES6 모듈
: 변수의 스코프는 좁으면 좁을수록 좋다.
: 파일 자체의 독자적인 모듈 스코프를 제공하기 때문에, 모듈 내부에서 선언한 변수는 더 이상 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
15장 let, const 키워드와 블록 레벨 스코프
- var 키워드로 선언한 변수의 문제점
- 변수 중복 선언 허용
- 함수 레벨 스코프
- 변수 호이스팅
: 의도치 않게 먼저 선언된 값이 변경되는 부작용이 발생한다.
: 함수 내부에서 선언되지 않는다면 전역 변수가 된다.
: 값 할당 이전에 참조할 경우, undefined가 반환된다.
- let 키워드
- 변수 중복 선언 금지
- 블록 레벨 스코프
- 변수 호이스팅
- 전역 객체와 let
: SyntaxError 발생
: 모든 코드 블록을 지역 스코프로 인정한다.
: let 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작한다. (참조 에러 발생)
선언 단계와 초기화 단계가 분리되어 진행되기 때문에, 초기화 이전에 변수에 접근하려고 하면 참조 에러(ReferenceError)가 발생하는데, 이 때 스코프의 시작 지점부터 초기화 지점까지 변수를 참조할 수 없는 구간을 일시적 사각지대(TDZ)라고 한다.
: let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아니며, 보이지 않는 개념적인 블록 내에 존재하게 된다.
- const 키워드
- 블록 레벨 스코프
- 변수 호이스팅
- 재할당 금지
- const 키워드와 객체
: const 키워드로 선언한 변수는 변수 호이스팅이 발생하지 않는 것처럼 동작한다. (참조 에러 발생)
: const 키워드로 선언된 변수에 객체를 할당한 경우 값을 변경할 수 있다. 변경 가능한 값인 객체는 재할당 없이도 직접 변경이 가능하다.
- var vs let vs const
: ES6 의 경우, var 키워드의 사용은 제한한다.
재할당이 필요한 경우, 최대한 좁은 스코프 내에서 let 키워드를 사용한다.
변경이 발생하지 않고 읽기 전용으로 사용하는 원시값과 객체는 const 키워드를 사용한다.