私は自分の仕事で使用するための小さなJSフレームワークを構築してきましたが、ダグラス・クロックフォードの典型的な遺伝形式を採用したいと思います。プロトタイプオブジェクトがどのように機能するかについての一般的な考え方は理解できたと思いますが、最も単純な例を超えてこのパターンを使用する方法が明確ではありません。
私はそれを理解できるところまで肉付けします。
(function () {
'use strict';
var Vehicles = {};
Vehicles.Vehicle = function () {
this.go = function () {
//go forwards
};
this.stop = function () {
//stop
};
};
Vehicles.Airplane = Object.create(Vehicles.Vehicle());
}());
これで、Vehicles.Airplaneオブジェクトはgo()とstop()を実行できますが、もっと必要です。このオブジェクトにtakeOff()メソッドとland()メソッドを追加したいと思います。後で醜いドット表記を使用することができます。
Vehicles.Airplane.takeOff = function () {
//take off stuff
}
しかし、特に多くのメソッドやプロパティを追加する場合は、それは間違っているようです。ここで尋ねられる質問は私のものと非常に似ているようですが、答えは私にはまったく当てはまりません。答えは、Object.createを使用する前にオブジェクトリテラルを作成する必要があり、そのオブジェクトリテラルをcreateメソッドに渡す必要があることを示しています。ただし、与えられたサンプルコードでは、新しいオブジェクトは現在何も継承していないように見えます。
私が望んでいるのは、次のような構文です。
Vehicles.Airplane = Object.create(Vehicles.Vehicle({
this.takeOff = function () {
//takeOff stuff
};
this.land = function () {
//land stuff
};
}));
もちろん、Vehicle.Vehicleにオブジェクトリテラルではなく関数を渡しているため、この構文はObject.createでひどく壊れることを知っています。それは重要なことではありません。事後にドット表記で一度に1つずつリストする必要なしに、別のプロパティから継承するオブジェクトに新しいプロパティをどのように構築する必要があるのか疑問に思っています。
編集:
ベルギ、このトピックについて苦悩した後、私はあなたが「古典的なパターン」と表現したものを本当に使いたいと思います。これが私の最初の刺し傷です(今では、仮説をモックアップするのではなく、実際のコードスニペットを使用しています-私のくだらないメソッドスタブを見ることができます):
CS.Button = function (o) {
o = o || {};
function init(self) {
self.domNode = dce('a');
self.text = o.text || '';
self.displayType = 'inline-block';
self.disabled = o.disabled || false;
self.domNode.appendChild(ctn(self.text));
if (o.handler) {
self.addListener('click', function () {
o.handler(self);
});
}
}
this.setText = function (newText) {
if (this.domNode.firstChild) {
this.domNode.removeChild(this.domNode.firstChild);
}
this.domNode.appendChild(ctn(newText));
};
init(this);
};
CS.Button.prototype = Object.create(CS.Displayable.prototype, {
constructor: {value: CS.Button, configurable: true}
});
CS.Displayable = function (o) { // o = CS Object
o = o || {};
var f = Object.create(new CS.Element(o));
function init(self) {
if (!self.domAnchor) {
self.domAnchor = self.domNode;
}
if (self.renderTo) {
self.renderTo.appendChild(self.domAnchor);
}
}
//Public Methods
this.addClass = function (newClass) {
if (typeof newClass === 'string') {
this.domNode.className += ' ' + newClass;
}
};
this.addListener = function (event, func, capture) {
if (this.domNode.addEventListener) {
this.domNode.addEventListener(event, func, capture);
} else if (this.domNode.attachEvent) {
this.domNode.attachEvent('on' + event, func);
}
};
this.blur = function () {
this.domNode.blur();
};
this.disable = function () {
this.disabled = true;
};
this.enable = function () {
this.disabled = false;
};
this.focus = function () {
this.domNode.focus();
};
this.getHeight = function () {
return this.domNode.offsetHeight;
};
this.getWidth = function () {
return this.domNode.offsetWidth;
};
this.hide = function () {
this.domNode.style.display = 'none';
};
this.isDisabled = function () {
return this.disabled;
};
this.removeClass = function (classToRemove) {
var classArray = this.domNode.className.split(' ');
classArray.splice(classArray.indexOf(classToRemove), 1);
this.domNode.className = classArray.join(' ');
};
this.removeListener = function () {
//Remove DOM element listener
};
this.show = function () {
this.domNode.style.display = this.displayType;
};
init(this);
};
CS.Displayable.prototype = Object.create(CS.Element.prototype, {
constructor: {value: CS.Displayable, configurable: true}
});
はっきり言って、まだうまくいっていないと言うべきですが、ほとんどの場合、私が正しい方向に進んでいるかどうかについてあなたの意見をお願いします。例のコメントで「インスタンス固有のプロパティとメソッド」について言及しました。これは、this.setTextメソッドなどが間違って配置されており、プロトタイプチェーンの子孫アイテムで使用できないことを意味しますか?
また、使用すると、宣言の順序が重要になるようです(CS.Buttonが最初にリストされているため、CS.Displayable.prototypeにアクセスできません。また、CS.Displayableは、その時点では未定義です。 mそれを参照しようとしています)。それは私がただ手直して対処しなければならないものですか(OCDのアルファベット順ではなく、祖先の順序でコードに入れてください)、それとも私が見落としているものがありますか?