본문으로 건너뛰기

작동 위임

[[Prototype]] 객체는 한 객체가 다른 객체를 참조하기 위한 내부 링크이다.

[[Prototype]]을 따라 필드나 메서드를 찾아가는 구조를 프로토타입 체이닝이라 한다.


6.1 위임 지향 디자인으로 가는 길

6.1.1 클래스 이론

  1. 부모 클래스를 설계
  2. 자식 클래스 정의 (상속)
  3. 메서드 오버라이드 및 확장
  4. super 사용 가능

6.1.2 위임 이론 (OLOO)

OLOO = Objects Linked to Other Objects

const Task = {
setId(id) { this.id = id },
outputId() { console.log(this.id) }
};

const XYZ = Object.create(Task);
XYZ.prepareTask = function(id, label) {
this.setId(id);
this.label = label;
};
XYZ.outputTaskDetails = function() {
this.outputId();
console.log(this.label);
};

const ABC = Object.create(Task);

특징:

  • 데이터 필드는 자식에 있고, 부모는 메서드만 가짐
  • 가려짐(shadowing)을 피하고 명확한 명칭을 권장
  • this는 실제 호출 객체를 참조
  • 상호 위임은 허용되지 않음 (루프 발생 위험)

6.1.3 클래스 vs 위임

클래스 기반 예시

function Foo(who) {
this.me = who;
}
Foo.prototype.identify = function() {
return `I am ${this.me}`;
};

function Bar(who) {
Foo.call(this, who);
}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.speak = function() {
alert(`Hello, ${this.identify()}.`);
};

OLOO 예시

const Foo = {
init(who) { this.me = who },
identify() { return `I am ${this.me}` }
};

const Bar = Object.create(Foo);
Bar.speak = function() {
alert(`Hello, ${this.identify()}.`);
};

const b1 = Object.create(Bar);
b1.init("b1");
b1.speak();

→ 단순하고 명확, 클래스 문법 없이 객체 연결


6.2 클래스 vs 객체 기반 위젯 예시

클래스 방식 (ES5/ES6 모두 예시)

  • Widget 클래스를 부모로 Button 클래스 상속
  • render를 오버라이드하고 기능 확장

OLOO 방식

const Widget = {
init(width, height) {
this.width = width;
this.height = height;
this.$elem = null;
},
insert($where) {
if (this.$elem) {
this.$elem.css({
width: this.width + "px",
height: this.height + "px"
}).appendTo($where);
}
}
};

const Button = Object.create(Widget);
Button.setup = function(width, height, label) {
this.init(width, height);
this.label = label;
this.$elem = $("<button>").text(this.label);
};
Button.build = function($where) {
this.insert($where);
this.$elem.click(this.onClick.bind(this));
};
Button.onClick = function() {
console.log(`${this.label} is clicked`);
};

6.3 더 간단한 설계

  • 객체를 직접 연결해 클래스 불필요
  • 인스턴스화 없이 Object.create 로 분리된 인스턴스 생성
  • 단일한 부모 컨트롤러 객체 없이도 설계 가능

6.4 최신 문법: 메서드 단축 구문

const LoginController = {
errors: [],
getUser() {},
getPassword() {}
};

const AuthController = {
errors: [],
checkAuth() {},
server(url, data) {}
};

Object.setPrototypeOf(AuthController, LoginController);
  • function 키워드 없이 선언 가능
  • Object.setPrototypeOf() 로 명시적 위임 설정

6.5 인트로스펙션 & 덕 타이핑

  • instanceof는 프로토타입 체인 기준 비교
  • 덕 타이핑은 속성 유무로 타입 판단
if (obj.something) {
obj.something();
}

then이 있으면 Promise로 간주하는 것도 덕 타이핑의 예

유연하지만 안전성 측면에선 제한적으로 사용할 것


6.6 정리

  • 클래스는 유일한 구조화 방법이 아님
  • 작동 위임(Delegation) 은 JS의 본래 [[Prototype]] 기반 설계
  • OLOO는 더 단순하고 유연한 대안
  • 객체 중심으로 생각하면 더 명확한 아키텍처 설계 가능