コードのウォークスルー:
- クラスは、提供された引数で init を呼び出す関数として定義されます。
new
これは、 egを使用して標準のコンストラクター構文で呼び出すことができることを意味します。適切な値で呼び出されvar instance = new Thingy()
た関数を取得します。init
this
- 親クラスを渡すと、そのクラスの
prototype
プロパティが新しい空のオブジェクトのプロトタイプ チェーンに追加され、それがその prototype
プロパティとして使用されます。最新のブラウザーでこれを行うより簡潔な方法は次のとおりです。_class.prototype = Object.create(parent.prototype);
init
関数が定義されています。これは、インスタンスが作成された後に、より便利な初期化コードでオーバーライドされる可能性があり_class
ます (または、クラスの作成時に関数を渡すことができるようにコードを変更する必要がありinit
ます... または、インスタンスがプロトタイプ チェーンをたどって検索できるようにする必要があります)。その他のinit
機能。
_class.fn
_class
コンストラクターのプロトタイプ関数への参照を提供するために作成されます。
_class.fn.parent
コンストラクターへの参照を提供するために作成されます。これは、プロトタイプを他のコンテキストに適用していて、プロトタイプのコンストラクターへの参照が必要な場合に役立ちます。
_class._super
コンストラクターの内部の非標準__proto__
プロパティが割り当てられます。コンストラクターは関数であり、Javascript では関数はオブジェクトであることに注意してください。これは、独自の内部プロトタイプがあることを意味します。以前の への参照prototype
は、このコンストラクターで作成されたオブジェクトに割り当てられたプロトタイプであり、コンストラクターのプロトタイプ自体ではありません。すべての関数は Function.prototype から継承します。ここでbind
、apply
などを取得します。_super
この場合は への参照にすぎませんFunction.prototype
。
このタイプの_super
がいつ使用されるかについては、次のことを想像できます。
function Maker(){ //this will be called as a constructor, ie. with new
var fun = function(){}; //Make a function
fun.__proto__ = this.__proto__; //yuck. Set the function's this value to the instance
return fun; //return the function
}
Maker.prototype={say:function(){console.log("Javascript is fun!.. And weird.")}};
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // undefined!!
うわー!今何があったの?実際、関数の内部プロトタイプをオブジェクトに置き換えました。これにより、興味深いプロトタイプ チェーンを構築し、関数とオブジェクトの両方を同様の方法で操作できます。ただし、 とのリンクFunction.prototype
は切断されているため、 にアクセスできないことに注意してくださいbind
。でも、もっと原型魔法で直しましょう!
function FunctionConnector(obj){
for (var prop in obj){
if(obj.hasOwnProperty(prop){
this.prop=obj.prop
}
}
}
FunctionConnector.prototype=Function.prototype;
Maker.prototype=new FunctionConnector({say:function(){
console.log("Javascript is fun!.. And weird.")
}});
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // function bind(){ [native code] }
今それは何FunctionConnector
ですか?オブジェクトを受け取り、コンストラクターとして呼び出されると、渡されたオブジェクトのすべてのプロパティを持ち、かつ から継承するオブジェクトを返しますFunction.prototype
。ご覧のとおり、 へのアクセスbind
が戻ってきました (もちろん、元の実装でFunction.prototype.bind.call
間に合わせて、勝利への道を進むこともできました)。
この新しいパターンを手に入れると_super
、コードで何をするのか、つまり、作成しているコンストラクターの組み込みプロトタイプを参照することがより明確になる場合が_class
あります (この例では、 のインスタンスは にFunctionConnector
なります_super
)。この参照を使用して、実行時にプロトタイプにパッチを適用したり、メソッドを呼び出しapply
たり、オブジェクトへの参照を使用できるその他のことを行うことができます。
これは、特に__proto__
非標準であるため、少しハックに気づいたかもしれません。しかし、それが可能にするパターンを楽しむなら、それはややきれいでもあります. Javascript の継承に関する知識に自信がある場合にのみ、このようなことを行うことをお勧めします。また、コード ベース全体を担当している場合を除き、そうではない可能性もあります。