시스템아 미안해
Chapter 6. The secret life of objects 본문
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
요약
- 객체는 프로토타입 체인을 통해 속성을 상속한다.
- 생성자와 class 문법으로 새로운 타입을 정의할 수 있다.
- getter/setter/static으로 속성을 제어하거나 클래스 메서드를 정의한다.
- 캡슐화(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 |