LHJ

I'm a FE developer.

9.2.6 다형성

10 May 2020 » js_lj

좀 어려워 보이는 다형성(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 같은 중요한 메서드를 상속하기 위해서이며, 염두에 둘 만큼 중요한 영향은 없습니다.