複製代碼 代碼如下:
/**
* 一個設計精巧的定時執行器
* 首先由 Class.create() 建立一個 PeriodicalExecuter 類型,
* 然後用對象直接量的文法形式設定原型。
*
* 需要特別說明的是 rgisterCallback 方法,它調用上面定義的函數原型方法bind, 並傳遞自己為參數。
* 之所以這樣做,是因為 setTimeout 預設總以 window 對象為當前對象,也就是說,如果 registerCallback 方法定義如下的話:
* registerCallback: function() {
* setTimeout(this.onTimerEvent, this.frequency * 1000);
* }
* 那麼,this.onTimeoutEvent 方法執行失敗,因為它無法訪問 this.currentlyExecuting 屬性。
* 而使用了bind以後,該方法才能正確的找到this,也就是PeriodicalExecuter的當前執行個體。
*/
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback();
} finally {
this.currentlyExecuting = false;
}
}
this.registerCallback();
}
}
具體Class.create()背後做了什麼,具體來看看Class的實現。
複製代碼 代碼如下:
/**
* 建立一種類型,注意其屬性 create 是一個方法,返回一個建構函式。
* 一般使用如下
* var X = Class.create(); 返回一個類型,類似於 java 的一個Class執行個體。
* 要使用 X 類型,需繼續用 new X()來擷取一個執行個體,如同 java 的 Class.newInstance()方法。
*
* 返回的建構函式會執行名為 initialize 的方法, initialize 是 Ruby 對象的構造器方法名字。
* 此時initialize方法還沒有定義,其後的代碼中建立新類型時會建立相應的同名方法。
*/
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
Class.create實際上是返回一個函數,那麼new的時候,做了些什麼呢。參照MDN
When the code new foo(...) is executed, the following things happen:
A new object is created, inheriting from foo.prototype.
The constructor function foo is called with the specified arguments and this bound to the newly created object. new foo is equivalent to new foo(), i.e. if no argument list is specified, foo is called without arguments.
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)
new的時候會執行該返回的函數,即執行this.initialize.apply(this, arguments); 此時的this就是新產生的對象,這也就是說了所有對象的初始化工作全部委託給initialize函數了。
-------
這裡為什麼要把自己的initialize方法綁定到自己身上??