以前JavaScriptで継承を実現する方法について書きましたが、幾つか改善点が見付かったので補足します。
上の記事で作成したコードを再掲します。
> function Currency(name, code) {
... this.name = name;
... this.code = code;
... }
undefined
> Currency.prototype.toString = function() {
... return this.name + " " + this.code;
... }
[Function]
> function CryptoCurrency(name, code, author) {
... this.name = name;
... this.code = code;
... this.author = author;
... }
undefined
> CryptoCurrency.prototype = new Currency()
Currency { name: undefined, code: undefined }
> CryptoCurrency.prototype.constructor = CryptoCurrency
[Function: CryptoCurrency]
> CryptoCurrency.prototype.base = Currency.prototype
Currency { toString: [Function] }
> CryptoCurrency.prototype.toString = function() {
... return this.base.toString.call(this) + " " + this.author;
... }
[Function]
子コンストラクタで親コンストラクタを呼ぶようにした方が良い
と思います。
上のコードでは子コンストラクタであるCryptoCurrency
コンストラクタでname
プロパティやcode
プロパティを定義していましたが、これらのプロパティは親コンストラクタから継承しているものなので、子コンストラクタで直接定義すべきではないでしょう。なので、子コンストラクタでは親コンストラクタを呼び出してこれらのプロパティは親コンストラクタに定義させるべきです。
> function CryptoCurrency(name, code, author) {
... Currency.call(this, name, code);
...
... this.author = author;
... }
undefined
Object.createを使うこともできる
上のコードでは子コンストラクタのprototype
プロパティを設定する際にnew
を使ってオブジェクトを実体化していましたが、new
の代わりにObject.create
を使うこともできます。
> CryptoCurrency.prototype = Object.create(Currency.prototype, {
... constructor: { value: CryptoCurrency, enumerable: false, writable: true, configurable: true },
... base: { value: Currency.prototype, enumerable: false, writable: true, configurable: true }
... })
CryptoCurrency {}