Prototype的Class.create解析
Prototype中的类的创建,一般使用Class.create方法来创建,例如PeriodicalExecuter类型。使用的时候通过调用new PeriodicalExecuter(xxx)来生成对象。
1 /**
2 * 一个设计精巧的定时执行器
3 * 首先由 Class.create() 创建一个 PeriodicalExecuter 类型,
4 * 然后用对象直接量的语法形式设置原型。
5 *
6 * 需要特别说明的是 rgisterCallback 方法,它调用上面定义的函数原型方法bind, 并传递自己为参数。
7 * 之所以这样做,是因为 setTimeout 默认总以 window 对象为当前对象,也就是说,如果 registerCallback 方法定义如下的话:
8 * registerCallback: function() {
9 * setTimeout(this.onTimerEvent, this.frequency * 1000);
10 * }
11 * 那么,this.onTimeoutEvent 方法执行失败,因为它无法访问 this.currentlyExecuting 属性。
12 * 而使用了bind以后,该方法才能正确的找到this,也就是PeriodicalExecuter的当前实例。
13 */
14 var PeriodicalExecuter = Class.create();
15 PeriodicalExecuter.prototype = {
16 initialize: function(callback, frequency) {
17 this.callback = callback;
18 this.frequency = frequency;
19 this.currentlyExecuting = false;
20
21 this.registerCallback();
22 },
23
24 registerCallback: function() {
25 setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
26 },
27
28 onTimerEvent: function() {
29 if (!this.currentlyExecuting) {
30 try {
31 this.currentlyExecuting = true;
32 this.callback();
33 } finally {
34 this.currentlyExecuting = false;
35 }
36 }
37
38 this.registerCallback();
39 }
40 }
具体Class.create()背后做了什么,具体来看看Class的实现。
1 /**
2 * 创建一种类型,注意其属性 create 是一个方法,返回一个构造函数。
3 * 一般使用如下
4 * var X = Class.create(); 返回一个类型,类似于 java 的一个Class实例。
5 * 要使用 X 类型,需继续用 new X()来获取一个实例,如同 java 的 Class.newInstance()方法。
6 *
7 * 返回的构造函数会执行名为 initialize 的方法, initialize 是 Ruby 对象的构造器方法名字。
8 * 此时initialize方法还没有定义,其后的代码中创建新类型时会建立相应的同名方法。
9 */
10 var Class = {
11 create: function() {
12 return function() {
13 this.initialize.apply(this, arguments);
14 }
15 }
16 }
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 andthis
bound to the newly created object.new foo
is equivalent tonew 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方法绑定到自己身上??