Study/모던 자바스크립트 Deep Dive

[모던 자바스크립트 Deep Dive] 21장 ~ 25장

chaeon1 2025. 3. 27. 22:28

21장 빌트인 객체

21.1 자바스크립트 객체의 분류

  1. 표준 빌트인 객체
    • ECMAScript 사양에 정의된 객체, 전역에서 공통 기능 제공
    • 실행 환경(브라우저/Node.js)과 관계 없이 언제나 사용 가능
    • Object, String, Number, Array, Promise, JSON
  2. 호스트 객체
    • ECMAScript 사양에는 없지만 실행 환경에서 제공하는 객체
    • 브라우저 환경: DOM, BOM, fetch, localStorage
    • Node.js 환경: fs, http Node.js 고유 API
  3. 사용자 정의 객체
    • 사용자가 직접 정의한 객체

21.2 표준 빌트인 객체

  • 생성자 함수 객체
    • Object, String, Number, Boolean, Array
    • new 키워드로 인스턴스 생성 가능
  • 비생성자 함수 객체
    • Math, JSON, Reflect
    • 인스턴스 생성 불가능, 정적 메서드만 제공

21.3 원시값과 래퍼 객체

  • 원시값(문자열, 숫자, 불리언)은 객체가 아니지만 래퍼 객체로 인해 객체처럼 동작
  • 래퍼 객체의 동작 과정
    • 원시값에 접근 시 자바스크립트 엔진이 래퍼 객체로 변환
    • 해당 객체에서 프로퍼티/메서드에 접근
    • 작업이 끝나면 다시 원시값으로 변환 및 가비지 컬렉션 대상

21.4 전역 객체

  • 코드 실행 전 생성되는 최상위 객체
  • 모든 빌트인 객체와 전역 변수/함수 포함
    • 브라우저 환경: window, self, frames, globalThis
    • Node.js 환경: global, globalThis
    • ECMAScript 2020부터는 환경에 관계없이 globalThis로 접근 가능
  • 전역 객체의 특징
    • 직접 생성 불가
    • 표준 빌트인 객체와 호스트 객체를 프로퍼티로 가짐
    • var로 선언한 전역 변수/함수는 전역 객체의 프로퍼티가 됨
    • letconst로 선언한 전역 변수는 전역 객체의 프로퍼티가 아님
  • 빌트인 전역 프로퍼티
    • Infinity: 무한대를 나타내는 숫자값 Infinity를 가짐
    • NaN: 숫자가 아님을 나타내는 숫자값 NaN을 가짐
    • undefined: 원시 타입 undefined를 값으로 가짐
  • 빌트인 전역 함수
    • eval: 자바스크립트 코드를 나타내는 문자열을 인수로 전달받음
    • isFinite: 전달받은 인수가 유한수이면 true 반환, 무한수이면 false반환
    • isNaN: 전달받은 인수가 NaN인시 검사, 불리언 타입으로 반환
    • parseFloat: 전달받은 문자열 인수를 실수로 해석하여반환
    • encodeURI / decodeURI: URI를 인수로 전달받아 이스케이프 처리
    • encodeURIComponent / decodeURIComponent: URI 구성 요소를 인수로 전달받아 인코딩/디코딩

22장 this

22.1 this 키워드

  • 객체: 상태(프로퍼티)와 동작(메서드)을 하나로 묶은 복합적 자료구조
  • 메서드는 자신이 속한 객체의 프로퍼티에 접근하거나 변경 가능해야 함
  • 객체 리터럴에서의 this
    • 메서드에서 자신이 속한 객체를 참조하려면 객체 식별자를 직접 참조할 수 있음
    • 객체를 직접 참조하는 방식은 비효율적
    • 따라서 this를 사용해 객체를 동적으로 참조

22.2 함수 호출 방식과 this 바인딩

함수 호출 방식 this 바인딩
일반 함수 호출 전역 객체
메서드 호출 메서드를 호출한 객체
생성자 함수 호출 생성자 함수가 (미래에) 생성할 인스턴스
Function.prototype.apply/call/bind 메서드에 의한 간접 호출 Function.prototype.apply/call/bind 메서드에 첫 번째 인수로 전달한 객체

23장 실행 컨텍스트

  • 실행 컨텍스트: 자바스크립트의 동작 원리를 이해하는 핵심 개념
  • 식별자와 바인딩된 값 관리, 스코프 체인, 호이스팅, 클로저, 비동기 처리 등 담당
  • 소스코드의 타입에 따라 서로 다른 실행 컨텍스트 생성

23.1 소스코드의 타입

소스코드 설명 생성되는 실행 컨텍스트
전역 코드 전역 범위에서 실행되는 코드 전역 실행 컨텍스트
함수 코드 함수 내부에서 실행되는 코드 함수 실행 컨텍스트
eval 코드 eval() 함수로 실행되는 코드 eval 실행 컨텍스트
모듈 코드 모듈 내부에 존재하는 코드 모듈 실행 컨텍스트

23.2 소스코드의 평가와 실행

  • 자바스크립트 엔진은 소스코드를 2개의 과정으로 처리
    • 소스코드 평가
      • 실행 컨텍스트 생성
      • 변수, 함수 선언문을 먼저 실행 (메모리 공간에 등록)
      • undefined로 초기화 (호이스팅 발생 원리)
    • 소스코드 실행
      • 코드가 순차적으로 실행
      • 변수 및 함수에 값 할당 및 연산 수행

23.3 실행 컨텍스트의 역할

  • 식별자 관리: 변수, 함수, 클래스 등을 실행 컨텍스트에서 등록 및 관리
  • 스코프 체인: 상위 스코프 참조로 변수 탐색을 가능하게 함
  • 코드 실행 순서 관리: 실행 중인 코드의 흐름 제어 (함수 호출 시 코드 흐름 변경)

23.4 실행 컨텍스트 스택

  • 실행 컨텍스트는 스택 자료구조로 관리
  • 코드가 실행되면 새로운 실행 컨텍스트가 생성되어 스택에 푸시
  • 실행이 끝나면 실행 컨텍스트가 팝하여 스택에서 제거

23.5 렉시컬 환경

  • 실행 컨텍스트 내부에서 식별자와 바인딩된 값을 관리하는 자료구조
  • 환경 레코드: 식별자와 값 저장
  • 외부 렉시컬 환경 참조: 스코프 체인 형성

23.6 실행 컨텍스트의 생성과 식별자 검색 과정

23.7 실행 컨텍스트와 블록 레벨 스코프


24장 클로저

  • 함수와 그 함수가 선언된 렉시컬 환경과의 조합

24.1 렉시컬 스코프

  • 정적 스코프
  • 함수를 어디서 호출했는지가 아니라 어디서 정의했는지에 따라 상위 스코프 결정
  • 함수가 선언된 위치에서 외부 변수에 접근할 수 있도록 저장

24.2 함수 객체의 내부 슬롯 [[Environment]]

  • 함수가 생성될 때 자신이 정의된 환경(상위 스코프)을 [[Environment]] 내부 슬롯에 저장
  • 함수가 호출되면 [[Environment]]를 통해 변수에 접근
  • 외부 함수가 종료된 후에도 해당 함수의 변수 참조 가능

24.3 클로저와 렉시컬 환경

  • 클로저: 함수가 생성될 때 결정된 상위 스코프를 계속 기억하는 특성
  • 외부 함수가 실행되면서 실행 컨텍스트 생성
  • 외부 함수의 실행이 종료되면 실행 컨텍스트 제거
  • 내부 함수가 반환되어 외부에서 참조되면
    • 내부 함수는 [[Environment]]에 저장된 외부 함수의 렉시컬 환경 참조
    • 따라서 외부 함수의 변수에 계속 접근 가능
  • 내부 함수가 호출될 때 외부 함수의 변수 값 유지

24.4 클로저의 활용

  • 상태를 안전하게 은닉하고 특성 함수에게만 상태 변경 허용
  • 상태를 안전하게 변경하고 유지하기 위해 사용할 수 있음

24.5 캡슐화와 정보 은닉

  • 캡슐화: 객체의 상태(프로퍼티)와 동작(메서드)을 하나로 묶는 것
  • 정보 은닉: 불필요한 변경을 방지하고 결합도를 낮추는 것

24.6 자주 발생하는 실수

  • 클로저를 사용하면 외부 함수의 변수가 계속 메모리에 유지됨
    • 불필요한 클로저 사용은 메모리 누수를 초래할 수 있음
    • 필요하지 않은 경우 변수를 null로 설정하여 참조 해제

25장 클래스

25.1 클래스는 프로토타입의 문법적 설탕인가?

  • 클래스: 새로운 객체 생성 메커니즘
  • 클래스와 생성자 함수의 차이점
    • 클래스는 new 연산자 없이 호출할 경우 에러 발생, 생성자 함수는 일반 함수처럼 실행 가능
    • 클래스는 extendssuper 키워드 지원, 상속을 보다 간편하게 구현 가능
    • 클래스는 선언 전에 참조 불가능, 호이스팅 시 Temporal Dead Zone(TDZ)에 빠짐
    • 클래스 내부는 strict mode 자동 적용
    • 클래스의 메서드는 [[Enumerable]]: false 속성, 열거되지 않음

25.2 클래스 정의

  • class 키워드를 사용하여 정의, 일반적으로 파스칼 케이스 사용
  • constructor: 인스턴스를 생성하고 초기화하는 역할을 하는 메서드
  • 프로토타입 메서드: 인스턴스를 통해 호출 가능
  • 정적 메서드: 클래스 자체에서 호출 가능

25.3 클래스 호이스팅

  • 클래스 선언문은 변수 선언문과 마찬가지로 호이스팅
  • let, const와 유사한 방식으로 동적하여 선언 전에 참조 불가능

25.4 인스턴스 생성

  • 클래스는 생성자 함수와 달리 new 없이 호출 불가능
  • 기명 클래스 표현식의 내부 이름은 클래스 내부에서만 유효

25.5 메서드

  • 클래스 내부에는 constructor, 프로토타입 메서드, 정적 메서드만 정의 가능
  • constructor
    • 클래스 내부에서 단 한 개만 정의 가능
    • constructor를 생략하면 빈 constructor()가 자동 추가
    • 생성자 함수와 달리 constructor는 클래스 평가 시 생성되는 코드의 일부
  • 프로토타입 메서드
    • 프로토타입 체인은 클래스에 생성된 인스턴스에도 동일하게 적용
    • 클래스는 생성자 함수와 마찬가지로 프로토타입 기반의 객체 생성 매커니즘
  • 정적 메서드
    • 클래스 정의 이후 인스턴스를 생성하지 않아도 호출 가능
    • 인스턴스로 클래스의 메서드를 상속받을 수 없음
  • 정적 메서드와 프로토타입 메서드의 차이
    • 정적 메서드와 프로토타입 메서드는 자신이 속해 있는 프로토타입 체인이 다름
    • 정적 메서드는 클래스로 호출 / 프로토타입 메서드는 인스턴스로 호출
    • 정적 메서드는 인스턴스 프로퍼티 참조 불가능 / 프로토타입 메서드는 인스턴스 프로퍼티 참조 가능
  • 클래스에서 정의한 메서드의 특징
    • function 키워드를 생략한 메서드 축약 표현 사용
    • 객체 리터럴과는 다르게 클래스에 메서드를 정의할 때는 콤마 필요 없음
    • 암묵적으로 strict mode로 실행
    • for...in 문이나 Object.keys 메서드 등으로 열거 불가능
    • 내부 메서드 [[Construct]]를 갖지 않는 non-constructor, new 연산자와 함께 호출할 수 없음

25.6 클래스의 인스턴스 생성 과정

  1. 인스턴스 생성과 this 바인딩
  2. 인스턴스 초기화
  3. 인스턴스 반환

25.7 프로퍼티

  • 인스턴스 프로퍼티
    • constructor 내부에서 정의
  • 접근자 프로퍼티
    • getter: get 키워드로 정의, 프로퍼티 값 조회 시 자동 호출
    • setter: set 키워드로 정의, 값 할당 시 자동 호출
  • 클래스 필드 정의 제안
    • 클래스의 접근자 프로퍼티는 프로토타입 프로퍼티로 정의
  • private 필드 정의 제안
    접근 가능성 public private
    클래스 내부 O O
    자식 클래스 내부 O X
    클래스 인스턴스를 통한 접근 O X
  • static 필드 정의 제안
    • static public 필드, static private 필드, static public 메서드 정의 가능

25.8 상속에 의한 클래스 확장

  • 클래스 상속과 생성자 함수 상속
    • 기존 클래스를 상속받아 새로운 클래스를 확장하여 정의
  • extends 키워드
    • 서브클래스: 상속을 통해 확장된 클래스
    • 수퍼클래스: 서브클래스가 상속하는 클래스
    • 클래스 간의 상속 관계 설정, 프로토타입 체인 형성
  • 동적 상속
    • extends 키워드는 생성자 함수도 상속 가능
    • 클래스 뿐만 아니라 생성자 함수처럼 평가되는 모든 표현식 사용 가능
  • 서브클래스의 constructor
    • constructor를 생략하면 빈 객체 생성
    • 서브클래스에서 constructor를 생략하면 부모 클래스의 constructor를 그대로 사용
  • super 키워드
    • super를 호출하면 수퍼클래스의 constructor 호출
    • super를 참조하면 수퍼클래스의 메서드 호출
  • 상속 클래스의 인스턴스 생성
    • 클래스를 상속하면 서브클래스는 직접 인스턴스를 생성하지 않고 수퍼클래스에게 위임
  • 표준 빌트인 생성자 함수 확장
    • String, Number, Array 같은 표준 빌트인 객체도 extends 키워드로 확장 가능