ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptの3つの継承実装方法_基礎知識
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 = Rectangle;
ユーティリティ ツール パッケージに付属する util.inherites を使用します
文法
util.inherits(constructor, 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 は ES6 の新機能で、指定されたオブジェクトのプロトタイプを別のオブジェクトまたは null に設定します
文法
Object.setPrototypeOf(obj, プロトタイプ)
obj はプロトタイプ化されるオブジェクトです
prototype は、obj の新しいプロトタイプです (オブジェクトまたは null にすることができます)。
nullに設定した場合は以下の例となります
Object.setPrototypeOf({}, null);
setPrototypeOf はその名の通り、遊びのためのプロトタイプに特化していると思います。
では、これはどのように実装されているのでしょうか?このとき、マスター __proto__
Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { obj.__proto__ = proto; return obj; }
proto を obj.__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'; } }
キーワードを使用した後は、さまざまなプロトタイプを設定する必要がなく、キーワードはカプセル化されているため、非常に高速で便利です。