좀 어려워 보이는 다형성(polymorphism) 이란 단어는 객체지향 언어에서 여러 슈퍼클래스의 멤버인 인스턴스를 가리키는 말입니다.
대부분의 객체지향 언어에서 다형성은 특별한 경우에 속합니다.
자바스크립트는 느슨한 타입을 사용하고 어디서든 객체를 쓸 수 있으므로(정확한 결과가 보장되진 않지만), 어떤 면에서는 자바스크립트의 객체는 모두 다형성을 갖고 있다고 할 수 있습니다.
자바스크립트 코드를 작성하다 보면 ‘이런 메서드가 있고 저런 메서드가 있으니 아마 그 클래스의 인스턴스일 것이다’ 처럼 집작할 때가 많습니다.
Car 예제에 적용해 본다면,
class Vehicle {
constructor() {
this.passengers = [];
console.log("Vehicle created");
}
addPassenger(p) {
this.passengers.push(p);
}
}
class Car extends Vehicle {
constructor() {
super();
console.log("Car created");
}
deployAirbags() {
console.log("BWOOSH!");
}
}
const v = new Vehicle();
v.addPassenger("Frank");
v.addPassenger("Judy");
v.passengers; // ["Frank", "Judy"]
const c = new Car();
c.addPassenger("Alice");
c.addPassenger("Cameron");
c.passengers; // ["Alice", "Cameron"]
v.deployAirbags(); // error
c.deployAirbags(); // "BWOOSH!"
deployAirbags 메서드가 있는 객체는 Car의 인스턴스라고 생각할 수 있습니다.
물론 아닐 수도 있지만, 그 같은 집작이 근거 없는 추측은 절대 아닙니다.
자바스크립트에는 객체가 클래스의 인스턴스인지 확인하는 instanceof 연산자가 있습니다.
이 연산자를 속일 수도 있지만, prototype과 __proto__ 프로퍼티에 손대지 않았다면 정확한 결과를 기대할 수 있습니다.
class Vehicle {
constructor() {
this.passengers = [];
console.log("Vehicle created");
}
addPassenger(p) {
this.passengers.push(p);
}
}
class Car extends Vehicle {
constructor() {
super();
console.log("Car created");
}
deployAirbags() {
console.log("BWOOSH!");
}
}
class Motorcycle extends Vehicle {}
const c = new Car();
const m = new Motorcycle();
c instanceof Car; // true
c instanceof Vehicle; // true
m instanceof Car; // false
m instanceof Motorcycle; // true
m instanceof Vehicle; // true
NOTE_
자바스크립트의 모든 객체는 루트 클래스인 Object의 인스턴스입니다.
즉, 객체 o에서 o instanceof Object는 항상 true입니다(__proto__ 프로퍼티를 수정한다면 다른 결과가 나올 수 있지만, 그렇게 해서는 안됩니다).
모든 객체가 Object의 인스턴스인 것은 toString 같은 중요한 메서드를 상속하기 위해서이며, 염두에 둘 만큼 중요한 영향은 없습니다.