/**
* 適切に設計された周期的エグゼキューター
* まず Class.create()、
* によって PeriodicalExecuter 型を作成し、次にオブジェクト リテラル構文を使用してプロトタイプを設定します。
*
* 特別な説明が必要なのは、rgisterCallback メソッドです。このメソッドは、上で定義した関数プロトタイプ メソッド binding を呼び出し、それ自体をパラメータとして渡します。
* これが行われる理由は、setTimeout がデフォルトで常にウィンドウ オブジェクトを現在のオブジェクトとして取得するためです。つまり、registerCallback メソッドが次のように定義されている場合です。
* registerCallback: function() {
* setTimeout(this. onTimerEvent, this.frequency * 1000);
* }
* その後、this.onTimeoutEvent メソッドは this.currentlyExecuting プロパティにアクセスできないため、実行に失敗します。
* バインドを使用した後、このメソッドは、PeriodicalExecuter の現在のインスタンスである this を正しく見つけることができます。
*/
var PeriodicalExecuter = クラス .create();
PeriodicalExecuter.prototype = {
initialize: function(callback,frequency) {
this.callback = callback
this.frequency =
this; .currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
setTimeout(this.onTimerEvent.bind(this), this.頻度 * 1000 );
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true; this.callback ();
} 最後に {
this.currentlyExecuting = false;
}
this.registerCallback()
}
Class.create() の背後で具体的に何が行われているか、Class の実装を見てみましょう。
コードをコピー
* 型を作成します。その属性 create はメソッドであり、コンストラクターを返すことに注意してください。
* は通常次のように使用されます。
* var X = Class.create(); は、Java の Class インスタンスと同様の型を返します。
* X 型を使用するには、Java の Class.newInstance() メソッドと同様に、引き続き new X() を使用してインスタンスを取得する必要があります。
*
* 返されたコンストラクターは、initialize という名前のメソッドを実行します。initialize は、Ruby オブジェクトのコンストラクター メソッドの名前です。
* この時点では初期化メソッドは定義されていません。後続のコードで新しい型を作成すると、同じ名前の対応するメソッドが確立されます。
*/
var Class = {
create: function() {
return function() {
this.initialize.apply(this, argument);
}
}
}
Class.create は実際には関数を返しますが、new が使用されるとどうなるでしょうか? MDN を参照してください。
コード new foo(...) が実行されると、次のことが起こります。
foo.prototype から継承して新しいオブジェクトが作成されます。
コンストラクター。関数 foo は指定された引数で呼び出され、新しく作成されたオブジェクトにバインドされた new foo は new foo() と同等です。つまり、引数リストが指定されていない場合、foo は引数なしで呼び出されます。
コンストラクターによって返されるオブジェクト。関数は新しい式全体の結果になります。コンストラクター関数が明示的にオブジェクトを返さない場合は、ステップ 1 で作成されたオブジェクトが代わりに使用されます (通常、コンストラクターは値を返しませんが、必要に応じて値を返すことを選択できます)。通常のオブジェクト作成プロセスをオーバーライドしたいと考えています。)
新規の場合、返された関数、つまり this.initialize.apply(this, argument) が実行されます。この時点では、これが新しく生成されたオブジェクトです。すべてのオブジェクトの初期化作業が初期化関数に委任されることを意味します。
------
なぜここで初期化メソッドを自分自身にバインドする必要があるのでしょうか? ?