시스템아 미안해

Chapter 6. The secret life of objects 본문

책/Eloquent Javascript

Chapter 6. The secret life of objects

if else 2025. 10. 1. 11:01

JavaScript의 객체는 단순히 키-값 쌍을 담는 그릇이 아니다.
프로토타입, 메서드, 클래스, 상속 등 다양한 기능을 통해 객체 지향 프로그래밍의 핵심 아이디어를 구현한다. 이 장에서는 그 주요 개념들을 정리한다.


1. 캡슐화 (Encapsulation)

  • 프로그램을 작은 조각으로 나누고, 각 조각이 자신의 상태를 관리하도록 한다.
  • 외부에 보여지는 인터페이스는 public, 내부 세부 구현은 private 개념이다.
  • 자바스크립트는 언어 차원의 private 구분은 없지만, 관습적으로 _속성명을 private처럼 사용한다.

핵심: 인터페이스와 구현을 분리하라.


2. 메서드와 this

  • 객체의 속성에 함수를 담으면 메서드가 된다.
  • 메서드로 호출하면 this가 해당 객체를 자동으로 가리킨다.
 
let rabbit = {
  type: "white",
  speak(line) {
    console.log(`The ${this.type} rabbit says '${line}'`);
  }
};

rabbit.speak("Hello");
// → The white rabbit says 'Hello'
  • call 메서드를 쓰면 this를 직접 지정할 수도 있다.
 
function speak(line) {
  console.log(`${this.type}: ${line}`);
}
speak.call({type: "hungry"}, "Give me carrot!");
  • 화살표 함수는 자신만의 this를 갖지 않고, 외부 스코프의 this를 그대로 사용한다.

3. 프로토타입 (Prototypes)

  • 객체에는 숨겨진 연결 고리, 즉 프로토타입이 있다.
  • 없는 속성을 접근하면, 자바스크립트는 프로토타입 체인을 따라 올라가며 찾는다.
  • 모든 객체의 뿌리는 Object.prototype이다.
 
console.log(Object.getPrototypeOf({}) === Object.prototype);
// → true
  • Object.create(proto)를 쓰면 원하는 프로토타입을 가진 객체를 만들 수 있다.

4. 클래스와 생성자

  • 전통적으로 생성자 함수 + prototype 조합으로 클래스처럼 썼다.
 
function Rabbit(type) {
  this.type = type;
}
Rabbit.prototype.speak = function(line) {
  console.log(`${this.type} says '${line}'`);
};
  • ES6 이후에는 class 문법이 생겨 더 깔끔해졌다.
 
class Rabbit {
  constructor(type) { this.type = type; }
  speak(line) { console.log(`${this.type} says '${line}'`); }
}

5. 속성 오버라이딩 (Overriding)

  • 객체에 같은 이름의 속성을 추가하면, 프로토타입에 있는 속성을 가린다.
 
Rabbit.prototype.teeth = "small";
let killerRabbit = new Rabbit("killer");
killerRabbit.teeth = "sharp";
console.log(killerRabbit.teeth); // → sharp

6. 다형성 (Polymorphism)

  • 특정 인터페이스(toString 등)를 가진 객체라면 어떤 타입이든 동일한 코드에서 사용할 수 있다.
 
Rabbit.prototype.toString = function() {
  return `a ${this.type} rabbit`;
};
console.log(String(new Rabbit("black")));
// → a black rabbit
  • 핵심: “인터페이스를 만족하기만 하면 타입이 달라도 동작한다.”

7. 심볼 (Symbols)

  • 고유한 속성 키를 만들기 위해 Symbol을 사용한다.
  • 문자열 키와 충돌하지 않는다.
 
const sym = Symbol("id");
obj[sym] = 123;

8. 반복자와 Iterable

  • for/of 루프에서 동작하려면 객체에 Symbol.iterator 메서드가 있어야 한다.
  • 이 메서드는 next()를 가진 iterator 객체를 반환해야 한다.
 
for (let char of "OK") console.log(char);
// → O
// → K
  • 직접 구현 예: Matrix 클래스와 MatrixIterator

9. Getter, Setter, Static

  • get 키워드: 속성 접근을 메서드처럼 동작시킴
  • set 키워드: 속성 할당 시 메서드 실행
  • static: 클래스 자체에 붙는 메서드
 
class Temp {
  constructor(celsius) { this.celsius = celsius; }
  get fahrenheit() { return this.celsius * 1.8 + 32; }
  set fahrenheit(v) { this.celsius = (v - 32) / 1.8; }
  static fromFahrenheit(v) { return new Temp((v - 32) / 1.8); }
}

10. 상속 (Inheritance)

  • 기존 클래스를 확장해 새로운 클래스를 정의할 수 있다.
 
class SymmetricMatrix extends Matrix {
  set(x, y, value) {
    super.set(x, y, value);
    if (x != y) super.set(y, x, value);
  }
}

11. instanceof

  • 객체가 특정 클래스의 인스턴스인지 확인하는 연산자.
 
console.log(new Rabbit("black") instanceof Rabbit);
// → true

요약

  1. 객체는 프로토타입 체인을 통해 속성을 상속한다.
  2. 생성자와 class 문법으로 새로운 타입을 정의할 수 있다.
  3. getter/setter/static으로 속성을 제어하거나 클래스 메서드를 정의한다.
  4. 캡슐화(encapsulation), 다형성(polymorphism), 상속(inheritance)은 자바스크립트 객체 시스템의 핵심이다.

👉 실무 팁

  • 직접 프로토타입 체인을 건드리기보다는 class 문법을 쓰는 게 가독성과 유지보수성에 유리하다.
  • 객체의 인터페이스를 분명히 하고, 구현 세부사항은 숨겨라.
  • 반복자(Symbol.iterator)를 구현하면 객체를 훨씬 더 유연하게 사용할 수 있다.

' > Eloquent Javascript' 카테고리의 다른 글

Chapter 9. Regular Expressions  (0) 2025.10.21
Chapter 8. Bugs and Errors  (0) 2025.10.20
Chapter 5. 고차 함수(Higher-Order Functions)  (0) 2025.09.30
Chapter 4. Data Structure: Objects And Arrays  (0) 2025.09.29
Chapter 3. Functions  (0) 2025.09.25