Object.create를 사용하여 클래스 상속 구현
다음은 공식홈페이지 예시입니다
//Shape - superclass function Shape() { this.x = 0; this.y = 0; } Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info("Shape moved."); }; // Rectangle - subclass function Rectangle() { Shape.call(this); //call super constructor. } Rectangle.prototype = Object.create(Shape.prototype); var rect = new Rectangle(); rect instanceof Rectangle //true. rect instanceof Shape //true. rect.move(1, 1); //Outputs, "Shape moved."
이때 Rectangle 프로토타입의 생성자는 상위 클래스를 가리킵니다. 자체 생성자를 사용해야 하는 경우 다음과 같이 수동으로 지정할 수 있습니다
Rectangle.prototype.constructor = 직사각형;
유틸리티 도구 패키지와 함께 제공되는 util.inherites 사용
문법
util.inherits(생성자, superConstructor)
예시
const util = require('util'); const EventEmitter = require('events'); function MyStream() { EventEmitter.call(this); } util.inherits(MyStream, EventEmitter); MyStream.prototype.write = function(data) { this.emit('data', data); } var stream = new MyStream(); console.log(stream instanceof EventEmitter); // true console.log(MyStream.super_ === EventEmitter); // true stream.on('data', (data) => { console.log(`Received data: "${data}"`); }) stream.write('It works!'); // Received data: "It works!"
이 역시 매우 간단한 예입니다. 실제로 소스 코드는 ES6의 새로운 기능을 사용합니다.
exports.inherits = function(ctor, superCtor) { if (ctor === undefined || ctor === null) throw new TypeError('The constructor to "inherits" must not be ' + 'null or undefined'); if (superCtor === undefined || superCtor === null) throw new TypeError('The super constructor to "inherits" must not ' + 'be null or undefined'); if (superCtor.prototype === undefined) throw new TypeError('The super constructor to "inherits" must ' + 'have a prototype'); ctor.super_ = superCtor; Object.setPrototypeOf(ctor.prototype, superCtor.prototype); };
그 중 Object.setPrototypeOf는 지정된 객체의 프로토타입을 다른 객체나 null로 설정하는 ES6의 새로운 기능입니다
문법
Object.setPrototypeOf(obj, 프로토타입)
obj는 프로토타입이 될 객체입니다
프로토타입은 obj의 새로운 프로토타입입니다(객체 또는 null일 수 있음).
Null로 설정하면 아래와 같은 예시입니다
Object.setPrototypeOf({}, null);
나는 setPrototypeOf가 그 이름에 걸맞은 재미를 위한 프로토타입을 전문으로 한다고 생각합니다.
그렇다면 이것은 어떻게 구현됩니까? 이때 마스터 __proto__를 사용해야 합니다
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { obj.__proto__ = proto; return obj; }
obj.__proto__에 proto를 할당하면 됩니다.
extends 키워드를 사용하세요
Java에 익숙한 학생들은 이 키워드에 대해 매우 잘 알고 있어야 합니다. Java에서의 상속은 이를 통해 구현됩니다.
ES6에 새로 추가된 클래스 키워드는 구문 설탕이지만 그 본질은 여전히 함수입니다.
다음 예제에서는 Polygon이라는 클래스를 정의한 후 Polygon을 상속하는 Square 클래스를 정의합니다. 생성자에서 사용하는 super()와 supper()는 생성자에서만 사용할 수 있으며, 이를 사용하기 전에 super 함수를 호출해야 한다는 점에 유의하세요.
class Polygon { constructor(height, width) { this.name = 'Polygon'; this.height = height; this.width = width; } } class Square extends Polygon { constructor(length) { super(length, length); this.name = 'Square'; } }
키워드를 사용한 후에는 다양한 프로토타입을 설정할 필요가 없습니다. 키워드가 캡슐화되어 있어 매우 빠르고 편리합니다.