Chapter 6

함수와 프로토타입

  • 6.1 객체지향 프로그래밍
  • 6.2 상속과 프로토타입
  • 6.3 프로토타입 객체
  • 6.4 프로토타입 체인과 오버라이딩
  • 6.5 instanceof, Object.create, 정적 메서드
  • 6.6 strict mode

JS는 프로토타입 기반 객체지향 언어야. 클래스 없이도 상속이 가능한 이 독특한 메커니즘을 이해하고, strict mode로 느슨한 문법까지 잡아보자.

이 책에서 가장 긴 챕터였던 프로토타입부터 보자. 모든 객체는 [[Prototype]] 내부 슬롯을 가지며, 이것이 상속을 구현하는 메커니즘이야. __proto__ 접근자 프로퍼티로 자신의 프로토타입에 접근할 수 있는데, 직접 사용보다 Object.getPrototypeOf/Object.setPrototypeOf를 쓰는 게 권장이야.

function Person(name) { this.name = name; }
Person.prototype.sayHello = function () { console.log(`Hi! ${this.name}`); };

const me = new Person('Lee');
me.sayHello(); // Hi! Lee — 프로토타입 체인으로 메서드를 상속받음

객체의 프로퍼티에 접근할 때, 해당 객체에 없으면 [[Prototype]]을 따라 부모 프로토타입에서 검색해. 이 검색 경로가 프로토타입 체인이야. 체인의 종점은 Object.prototype이고, 여기서도 못 찾으면 undefined를 반환하지. 스코프 체인이 식별자를 찾는 메커니즘이라면, 프로토타입 체인은 프로퍼티를 찾는 메커니즘이야. 둘은 협력해서 동작해.

인스턴스에 프로토타입과 같은 이름의 프로퍼티를 추가하면, 프로토타입 프로퍼티를 덮어쓰는 게 아니라 인스턴스 프로퍼티로 추가돼. 프로토타입 프로퍼티가 가려지는 현상을 섀도잉이라고 해.

obj instanceof Constructor는 obj의 프로토타입 체인 상에 Constructor.prototype이 존재하면 true를 반환해. Object.create는 프로토타입을 직접 지정하면서 새 객체를 생성하는 메서드야.

const obj = Object.create(null); // 프로토타입이 null인 객체

정적 프로퍼티/메서드는 생성자 함수 자체에 추가된 것들이야. 인스턴스로 호출할 수 없고, Object.keys(), Object.freeze() 같은 것들이 여기에 해당하지.

이어서 strict mode를 보자. 'use strict';를 선언하면 JS 엔진이 코드를 더 엄격하게 검사해. 암묵적 전역 같은 실수를 에러로 잡아주거든.

'use strict';
x = 10; // ReferenceError — 선언하지 않은 변수에 할당

strict mode가 잡아주는 에러들이 있어. 선언 없이 변수 사용하면 ReferenceError, delete로 변수/함수/매개변수 삭제 시도하면 SyntaxError, 매개변수 이름이 중복되면 SyntaxError. 동작이 달라지는 부분도 있는데, 일반 함수의 thisundefined로 바인딩돼(비strict에서는 전역 객체). 전역이나 함수 단위로 적용하면 문제가 생길 수 있어서 즉시 실행 함수 단위가 바람직한데, 실무에서는 ESM이나 클래스가 자동으로 strict mode이니까 크게 고민할 필요 없어.


정리

6장 읽고 기억할 거 세 가지:

  1. 프로토타입 체인은 JS 상속의 핵심이야. 프로퍼티에 접근할 때 객체 자신에 없으면 체인을 따라 올라가서 찾지.
  2. 같은 이름의 프로퍼티를 인스턴스에 추가하면 섀도잉이 일어나. 프로토타입 프로퍼티를 덮어쓰는 게 아니라 가려지는 거야.
  3. strict mode는 실수를 에러로 바꿔주는 안전장치이고, 모던 JS에서는 ESM과 클래스가 자동으로 strict mode야.