OSDN Git Service

Version 0.6.176, add X.Script.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 13_XClass.js
1 \r
2 // ------------------------------------------------------------------------- //\r
3 // ------------ local variables -------------------------------------------- //\r
4 // ------------------------------------------------------------------------- //\r
5 var\r
6         /**\r
7          * 全てのクラスのスーパークラスのようなもの。(ライブラリ内にカプセル化されているため、ユーザが触ることはありません)<br>\r
8          * X.Class.create() で定義されたクラスのインスタンスが共通で備えるメソッド を確認してください。\r
9          * @class __ClassBase__\r
10          * @private\r
11          * @abstract\r
12          */\r
13         __ClassBase__ = {\r
14                         /**\r
15                          * クラス名\r
16                          * @type {string}\r
17                          */\r
18                         name         : ''\r
19                 },\r
20 \r
21         X_Class_CLASS_LIST         = [],\r
22         X_Class_DEF_LIST           = [],\r
23         X_Class_CALLING_SUPER      = [],\r
24         X_Class_CALL_SUPER_STACK   = [],\r
25         X_Class_traits             = null,\r
26         X_Class_useObjectCreate    = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf\r
27         // Opera Mobile 12.10 Android11 IS01 でクラスのメンバが欠落する問題に遭遇。__proto__ を辞めると動作,,,\r
28         X_Class_use_proto_         = !X_UA[ 'OperaMobile' ] && !X_UA[ 'OperaTablet' ] && !!X_emptyFunction.prototype.__proto__,\r
29         X_Class_SEAL_KILLING       = [],\r
30 \r
31 X_Class_CommonMethods =\r
32 /** @lends __ClassBase__.prototype */\r
33 {\r
34         /**\r
35          * 全ての動的メンバを削除して、インスタンスを破棄する。<br>\r
36          * インスタンスが X.EventDispatcher とそのサブクラスの場合、次の動作をする。\r
37          * <ol>\r
38          * <li>X.Event.BEFORE_KILL_INSTANCE を発火する。戻り値のビットフラグに X_Callback.PREVENT_DEFAULT が立つ場合、破棄をキャンセルし X.Event.KILL_INSTANCE_CANCELED を発火する。この間に kill() が呼ばれても無視される。\r
39          * <li>破棄に進む場合は、X.Event.KILL_INSTANCE を発火する。\r
40          * <li>dispatch 中は、インスタンスの全ての dispatch が終了するまで実際の破棄を待つ。\r
41          * <li>実際の破棄では、インスタンスのメンバの削除に加えて全てのイベントリスナを解除する。\r
42          */\r
43         // TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ\r
44         'kill' : function(){\r
45                 var listeners, flag, p, timers, def;\r
46                 \r
47                 // TODO 破棄済のインスタンスへの kill\r
48                 \r
49                 if( this[ 'instanceOf' ]( X_EventDispatcher ) ){\r
50 \r
51                         listeners = this[ '_listeners' ];\r
52 \r
53                         // SEAL のタイミングは、イベント中なので listeners が存在する\r
54                         if( listeners && X_Class_SEAL_KILLING.length && X_Class_SEAL_KILLING.indexOf( this ) !== -1 ) return;\r
55 \r
56                         // listeners がない場合、イベントの登録がないため、BEFORE_KILL_INSTANCE は呼ばれない。\r
57                         // KILL_RESERVED == true の場合、BEFORE_KILL_INSTANCE は呼ばれない。\r
58                         if( listeners && !listeners[ X_LISTENERS_KILL_RESERVED ] && listeners[ X_EVENT_BEFORE_KILL_INSTANCE ] ){\r
59                                 X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this;\r
60                                 \r
61                                 if( this[ 'dispatch' ]( X_EVENT_BEFORE_KILL_INSTANCE ) & X_CALLBACK_PREVENT_DEFAULT ){\r
62                                         this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE_CANCELED );\r
63                                         // BEFORE_KILL_INSTANCE, KILL_INSTANCE_CANCELED 内で kill() しても PREVENT_DEFAULT の場合はこれを無視する。\r
64                                         flag = true;\r
65                                 };\r
66                                 \r
67                                 X_Class_SEAL_KILLING.length === 1 ?\r
68                                         ( X_Class_SEAL_KILLING.length = 0 ) :\r
69                                         X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
70 \r
71                                 if( flag ) return;\r
72                         };\r
73 \r
74                         if( listeners = this[ '_listeners' ] ){// unlisten 等で listeners が破棄されている場合があるので取り直し。\r
75                                 if( listeners[ X_LISTENERS_DISPATCHING ] ){\r
76                                         listeners[ X_LISTENERS_KILL_RESERVED ] = true;\r
77                                         return;\r
78                                 };\r
79                                 \r
80                                 if( listeners[ X_EVENT_KILL_INSTANCE ] ){\r
81                                         X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this;\r
82 \r
83                                         listeners[ X_LISTENERS_KILL_RESERVED ] = false;                                 \r
84                                         this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE );\r
85                                         \r
86                                         X_Class_SEAL_KILLING.length === 1 ?\r
87                                                 ( X_Class_SEAL_KILLING.length = 0 ) :\r
88                                                 X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
89                                 };\r
90                                 \r
91                                 X_EventDispatcher_unlistenAll( this );\r
92                         };\r
93 \r
94                         if( this[ 'instanceOf' ]( Node ) ){\r
95                                 // console.log( 'KILL : ' + this.call( 'outerHTML' ) );\r
96                                 X_Node_onKill( this );\r
97                         };\r
98 \r
99                         timers = X_EventDispatcher_LAZY_TIMERS;\r
100 \r
101                         // asyncDispatch の削除\r
102                         for( p in timers ){\r
103                                 if( timers[ p ] === this ){\r
104                                          // delete X_EventDispatcher_LAZY_TIMERS[ p ]; コレ不要\r
105                                         X_Timer_remove( p );\r
106                                 };\r
107                         };\r
108                 };\r
109                 \r
110                 X_Object_clear( this );\r
111                 \r
112                 def = X_Class_getClassDef( this );\r
113                 \r
114                 if( def.pool ){\r
115                         def.live.splice( def.live.indexOf( this ), 1 );\r
116                         def.pool[ def.pool.length ] = this;\r
117                 };\r
118         },\r
119         \r
120         /**\r
121          * 関数は Constructor 内で使用します。クラス定義を辿ってスーパークラスのコンストラクタを探します。<br>\r
122          * 内部的には、呼び出したコンストラクタは配列に控え(X_Class_CALLING_SUPER)、呼び出したコンストラクタ内でさらに Super が呼ばれた場合、配列を元にさらにスーパーなコンストラクタを辿ります。\r
123          * @example Constructor : function( arg1, arg2 ){\r
124          *      this.Super( aeg1, arg2 );\r
125          * }\r
126          * @param var_args {...?} 親コンストラクタを呼ぶ際に渡す任意の数の引数\r
127          * @return {*}\r
128          */\r
129         // TODO 現在 new しているインスタンスを保持してチェックする\r
130         'Super' : function( var_args ){\r
131                 var sClass = this,\r
132                         i      = X_Class_CALLING_SUPER.indexOf( sClass ),\r
133                         l, sList, def, sConst, ret;\r
134         \r
135                 if( i === -1 ){\r
136                         X_Class_CALLING_SUPER[ l = X_Class_CALLING_SUPER.length ] = sClass;\r
137                         X_Class_CALL_SUPER_STACK[ l ] = sList = [];\r
138                         def = X_Class_getClassDef( sClass );\r
139                         if( !def.Constructor ) sClass = def.SuperClass;// 現在のクラスがコンストラクタを持たない場合 SuperConstructor を new で呼んでいるため再び呼ばないようにする\r
140                 } else {\r
141                         sList = X_Class_CALL_SUPER_STACK[ i ];\r
142                 };\r
143                 \r
144                 while( sClass ){\r
145                         def    = X_Class_getClassDef( sClass );\r
146                         sClass = def.SuperClass;\r
147                         sConst = def.SuperConstructor;\r
148                         if( !sConst ) break;\r
149                         if( sList.indexOf( sConst ) === -1 ){\r
150                                 sList[ sList.length ] = sConst;\r
151                                 ret = sConst.apply( this, arguments );\r
152                                 --sList.length;\r
153                                 if( !sList.length ){\r
154                                         X_Class_CALLING_SUPER.splice( i, 1 );\r
155                                         X_Class_CALL_SUPER_STACK.splice( i, 1 );\r
156                                 };\r
157                                 return ret;\r
158                         };\r
159                 };\r
160                 console.log( 'スーパークラスのコンストラクタが見つかりません' );\r
161         },\r
162 \r
163         /**\r
164          * func について、親クラスで設定されている同名の関数メンバーを呼び出す。<br>\r
165          * 第一引数に関数を指定し、2つ以上の異なる名前で同じ関数がメンバーがいた場合、動作が不確実になります。<br>\r
166          * 参考:<a href="http://qiita.com/no22@github/items/d3bead2acbb7ff1fb86b" target="_blank">ES5なJavascriptでモダンなクラス的継承&スーパー呼び出し </a>\r
167          * @param funcNameOrFunc {Function|string} スーパークラスの関数名 または、オーバーライド済の自身の関数。\r
168          * @param var_args {...*} オーバーライド元関数に渡す任意の数の引数\r
169          * @example return this.superCall( arguments.callee, param0, param1, ... );\r
170          * @return {*} オーバーライド元の関数を呼び出した戻り値。\r
171          */\r
172         'superCall' : function( funcNameOrFunc, var_args ){\r
173                 var sClass = this,\r
174                         args   = arguments,\r
175                         name, p, sFunc, hit = false;\r
176                 if( X_Type_isFunction( funcNameOrFunc ) ){\r
177                         for( p in this.constructor.prototype ){\r
178                                 if( this.constructor.prototype[ p ] === funcNameOrFunc ){\r
179                                         name = p;\r
180                                         break;\r
181                                 };\r
182                         };\r
183                         if( !name ) return;\r
184                 } else {\r
185                         return;\r
186                 };\r
187                 \r
188                 if( X_EMPTY_OBJECT[ name ] ) return;\r
189                 \r
190                 while( sClass ){\r
191                         def    = X_Class_getClassDef( sClass );\r
192                         sClass = def.SuperClass;\r
193                         sFunc  = sClass.prototype[ name ];\r
194                         if( sFunc === funcNameOrFunc ){\r
195                                 hit = true; // 現在の関数にヒット\r
196                         } else\r
197                         if( hit && X_Object_inObject( name, this ) ){\r
198                                 if( X_Type_isFunction( sFunc ) ){\r
199                                         switch( args.length ){\r
200                                                 case 1 :\r
201                                                         return sFunc.call( this );\r
202                                                 case 2 :\r
203                                                         return sFunc.call( this, args[ 1 ] );\r
204                                                 case 3 :\r
205                                                         return sFunc.call( this, args[ 1 ], args[ 2 ] );\r
206                                                 case 4 :\r
207                                                         return sFunc.call( this, args[ 1 ], args[ 2 ], args[ 3 ] );\r
208                                                 default :\r
209                                                         args = X_Array_copy( args );\r
210                                                         args.shift();\r
211                                                         return sFunc.apply( this, args );\r
212                                         };\r
213                                 };\r
214                                 break;\r
215                         };\r
216                 };\r
217         },\r
218         \r
219         /**\r
220          * インスタンスのクラスか?またはスーパークラスか?調べる。<br>\r
221          * instanceof 構文をサポートしない環境(IE4,Mac IE5)を想定する場合、必ずこのメソッドを使用すること。<br>\r
222          * クラスのインスタンスか?だけ調べたい場合は this.constructor === klass が高速。\r
223          * @param klass {__ClassBase__} クラス定義\r
224          * @return {boolean}\r
225          */\r
226         // TODO instanceof に対応したブラウザはそちらを使用\r
227         'instanceOf' : function( klass ){\r
228                 var Super = this;\r
229                 if( this.constructor === klass ) return true;\r
230                 while( Super = X_Class_getClassDef( Super ).SuperClass ){\r
231                         if( Super === klass ) return true;\r
232                 };\r
233                 return false;\r
234         }\r
235 };\r
236 \r
237 // ------------------------------------------------------------------------- //\r
238 // --- interface ----------------------------------------------------------- //\r
239 // ------------------------------------------------------------------------- //\r
240 \r
241 /**\r
242  * @enum {number}\r
243  * @const\r
244  */\r
245 var X_Class = {\r
246         NONE         :  0,\r
247         POOL_OBJECT  :  1,\r
248         ABSTRACT     :  2,\r
249         FINAL        :  4,\r
250         SINGLETON    :  8\r
251 };\r
252 \r
253 /**\r
254  * <p>Class を定義し システムの管理下に置く。\r
255  * <p>prototype 継承のブラウザ毎の差異も吸収し、 以下から最適な方法をしてくれる。\r
256  * \r
257  * <ol>\r
258  * <li>Object.create はパフォーマンスが悪そうなので現在は使っていない。\r
259  * <li>SubClass.prototype.__proto__ = SuperClass.prototype;\r
260  * <li>SubClass.prototype = new SuperClass;\r
261  * </ol>\r
262  * \r
263  * <ol>\r
264  * <li>X.Class.create( opt_settings, opt_name, opt_props ) でクラスを登録.\r
265  * <li>コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く.\r
266  * <li>通常通り new で インスタンス生成\r
267  * <li>kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
268  * <li>pool が有効の場合、new で pool されたインスタンスが返される.\r
269  * </ol>\r
270  * @namespace X.Class\r
271  * @alias X.Class\r
272  */ \r
273 X[ 'Class' ] = /** @lends X.Class */ {\r
274 \r
275     /**\r
276      * 設定なし。\r
277      * @const\r
278      */ \r
279         'NONE'         : X_Class.NONE,\r
280         \r
281     /**\r
282      * インスタンスは破棄時(this.kill())に回収され、次回の new MyClass() 時に再利用されます。\r
283      * @const\r
284      */\r
285         'POOL_OBJECT'  :  X_Class.POOL_OBJECT,\r
286         \r
287         /**\r
288          * 定義するクラスは抽象クラスになります。new AbstractClass() とするとエラーになります。\r
289          * @const\r
290          */\r
291         'ABSTRACT'     :  X_Class.ABSTRACT,\r
292 \r
293         /**\r
294          * クラスの継承を禁止する。\r
295          * @const\r
296          */\r
297         'FINAL'        :  X_Class.FINAL,\r
298 \r
299         /**\r
300          * 未実装。でも目印になるので付けておきましょう。\r
301          * @const\r
302          */\r
303         'SINGLETON'    : X_Class.SINGLETON,\r
304 \r
305         'create'       : X_Class_create\r
306         \r
307         // TODO collect\r
308 };\r
309 \r
310 \r
311 \r
312 // ------------------------------------------------------------------------- //\r
313 // --- implements ---------------------------------------------------------- //\r
314 // ------------------------------------------------------------------------- //\r
315         /**\r
316          * クラスを定義する。<br>\r
317          * X.Class.create() によるクラス定義は必ずしもコンストラクタ('Constructor')を必要としません。クラス定義時にコンストラクタが未設定の場合、スーパークラスがあればそのコンストラクタを使用します。\r
318          * @alias X.Class.create\r
319          * @param {string} [displayName] クラスの名前\r
320          * @param {number} [classSetting=0] X_Class.POOL_OBJECT | X_Class.FINAL など\r
321          * @param {object} [props={}] このクラスのメンバと関数。コンストラクタは Constructor と書くこと\r
322          * @return {__ClassBase__}\r
323          * @example var myClass = X.Class.create(\r
324          *      'myClass',\r
325          *  X.Class.FINAL,\r
326          *  {\r
327          *       name : '',\r
328          *       Constructor : function( obj ){\r
329          *        this.name = obj.name;\r
330          *       },\r
331          *       getName : function(){\r
332          *        return this.name;\r
333          *       },\r
334          *       setName : function(v){\r
335          *        this.name = v;\r
336          *       }\r
337          *  }\r
338          * );\r
339          */\r
340         function X_Class_create( /* displayName, classSetting, privateClass, props */ ){\r
341                 var args        = X_Array_copy( arguments ),\r
342                         displayName = args[ 0 ],\r
343                         classSetting,\r
344                         opt_pool, opt_abstract, opt_final,\r
345                         privateDef,\r
346                         props,\r
347                         klass,\r
348                         classDef = {},\r
349                         cbHash = { proxy : X_Class_actualConstructor, classDef : classDef };\r
350 \r
351                 if( X_Type_isString( displayName ) === true ){\r
352                         classDef.displayName = displayName;\r
353                         args.shift();\r
354                 };\r
355                 \r
356                 // クラス設定\r
357                 classDef.setting = classSetting = args[ 0 ];\r
358                 if( X_Type_isNumber( classSetting ) ){\r
359                         opt_pool     = !!( classSetting & X_Class.POOL_OBJECT  );\r
360                         opt_abstract = !!( classSetting & X_Class.ABSTRACT     );\r
361                         opt_final    = !!( classSetting & X_Class.FINAL        );\r
362                         if( opt_final && opt_abstract ){\r
363                                 X.Logger.critical( 'final & Abstract!' );\r
364                                 return;\r
365                         };      \r
366                         args.shift();\r
367                 } else {\r
368                         classDef.setting = 0;\r
369                 };\r
370                 \r
371                 // インスタンスのメンバー\r
372                 props = args[ 0 ];\r
373                 if( !X_Type_isObject( props ) ){\r
374                         // クラスメンバ用オブジェクトが無しでもクラスは作成可能\r
375                         props = {};\r
376                 } else\r
377                 if( props[ 'Constructor' ] ){\r
378                         //{+dev\r
379                         if( !X_Type_isFunction( props[ 'Constructor' ] ) ){\r
380                                 alert( '"Constructor" is not function.' );\r
381                                 return;\r
382                         };\r
383                         //}+dev\r
384                         classDef.Constructor = props[ 'Constructor' ];\r
385                 };\r
386 \r
387                 klass  = X_Closure_actualClosure( cbHash ); // TODO callbackHash を class定義の置き場所にしてしまう!なるほど…\r
388                 cbHash.klass = klass;\r
389                 klass[ 'superClassOf' ] = X_Class_superClassOf;\r
390                 klass[ 'subClassOf' ]   = X_Class_subClassOf;\r
391                 \r
392                 if( X_Class_useObjectCreate ){\r
393                         klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonMethods, false );\r
394                         klass.prototype.constructor = klass;\r
395                 } else\r
396                 if( X_Class_use_proto_ ){\r
397                         X_Class_override( klass.prototype, props, true );\r
398                         if( X_Class_traits ){\r
399                                 klass.prototype.__proto__ = X_Class_traits;\r
400                         } else {\r
401                                 X_Class_override( klass.prototype, X_Class_CommonMethods, false );\r
402                         };\r
403                 } else {\r
404                         klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonMethods, false );\r
405                         klass.prototype.constructor = klass;\r
406                 };\r
407                 \r
408                 klass[ 'name' ] = displayName;\r
409                 \r
410                 if( opt_abstract ){\r
411                         classDef.isAbstract = true;\r
412                 } else\r
413                 if( opt_pool ){\r
414                         classDef.pool = [];\r
415                         classDef.live = [];\r
416                 };                      \r
417                 if( opt_final ){\r
418                         classDef.Final = true;\r
419                 } else {\r
420                         klass[ 'inherits' ] = X_Class_inherits;\r
421                 };                      \r
422                 \r
423                 X_Class_CLASS_LIST.push( klass );\r
424                 X_Class_DEF_LIST.push( classDef );                              \r
425 \r
426                 return klass;\r
427         };\r
428 \r
429 \r
430 \r
431 function X_Class_getClass( instance ){\r
432         var cList    = X_Class_CLASS_LIST,\r
433                 i        = cList.length,\r
434                 klass;\r
435         for( ; i; ){\r
436                 klass = cList[ --i ];\r
437                 if( instance.constructor === klass ) return klass;\r
438         };\r
439         if( cList.indexOf( instance ) !== -1 ) return instance;\r
440 };\r
441 \r
442 function X_Class_getClassDef( KlassOrInstance ){\r
443         var i = X_Class_CLASS_LIST.indexOf( KlassOrInstance );\r
444         if( i === -1 ) i = X_Class_CLASS_LIST.indexOf( X_Class_getClass( KlassOrInstance ) );\r
445         if( i !== -1 ) return X_Class_DEF_LIST[ i ];\r
446         \r
447         if( X_Class_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
448 };\r
449 \r
450 /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
451 function X_Class_override( target, src, force ){\r
452         var p;\r
453         for( p in src ){\r
454                 if( p === 'Constructor' ) continue;\r
455                 if( p === '__proto__' || p === 'prototype' || p === 'constructor' ){\r
456                         X.Logger.critical( p + ' is reserved!' );\r
457                         return;\r
458                 };\r
459                 if( force || target[ p ] === undefined ){\r
460                         target[ p ] = src[ p ];\r
461                 };\r
462         };\r
463         return target;\r
464 };\r
465 \r
466 /**\r
467  * スーパークラスか?調べます。\r
468  * @alias __ClassBase__.superClassOf\r
469  * @param klass {__ClassBase__}\r
470  * @return {boolean}\r
471  */\r
472 function X_Class_superClassOf( klass ){\r
473         var myDef      = X_Class_getClassDef( this ),\r
474                 targetDef  = X_Class_getClassDef( klass ),\r
475                 SuperClass = klass;\r
476 \r
477         if( !myDef || !targetDef || this === klass ) return false;\r
478         \r
479         while( SuperClass = X_Class_getClassDef( SuperClass ).SuperClass ){\r
480                 if( SuperClass === this ) return true;\r
481         };\r
482         \r
483         return false;\r
484 };\r
485 \r
486 /**\r
487  * サブクラスか?調べます。\r
488  * @alias __ClassBase__.subClassOf\r
489  * @type {Function}\r
490  * @param klass {__ClassBase__}\r
491  * @return {boolean}\r
492  */\r
493 function X_Class_subClassOf( klass ){\r
494         return klass && X_Class_superClassOf.call( klass, this );\r
495 };\r
496                         \r
497 /**\r
498  * サブクラスを作ります。与える引数は X_Class.create と同じです。http://d.hatena.ne.jp/m-hiyama/20051018/1129605002\r
499  * @alias __ClassBase__.inherits\r
500  * @example var SubClass = SuperClass.inherits( 'Sub', X_Class.FINAL, { ... } );\r
501  * @param {string} [displayName] クラスの名前\r
502  * @param {number} [classSetting=0] X_Class.POOL_OBJECT | X_Class.FINAL など\r
503  * @param {object} [props={}] このクラスのメンバと関数。コンストラクタは Constructor と書くこと\r
504  * @return {__ClassBase__}\r
505  */\r
506 function X_Class_inherits( /* displayName, classSetting, props */ ){\r
507         var args        = X_Array_copy( arguments ),\r
508                 params      = [],\r
509                 Super       = this,\r
510                 superDef    = X_Class_getClassDef( Super ),\r
511                 displayName = args[ 0 ],\r
512                 classSetting,\r
513                 //opt_super,\r
514                 klass, def;\r
515         if( superDef.Final ) X.Logger.critical( 'X.Class inherits, Class is final!' );\r
516         \r
517         // サブクラス名\r
518         if( X_Type_isString( displayName ) ){\r
519                 args.shift();\r
520         } else {\r
521                 displayName = 'SubClass of ' + superDef.displayName;\r
522         };\r
523         params.push( displayName );\r
524         \r
525         // サブクラス設定\r
526         classSetting = args[ 0 ];\r
527         if( X_Type_isNumber( classSetting ) ){\r
528                 args.shift();\r
529         } else {\r
530                 // クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
531                 classSetting = superDef.setting;// &= ~X_Class.ABSTRACT;\r
532         };\r
533 \r
534         params.push( classSetting );\r
535 \r
536         // サブクラスのシャドウ\r
537         if( args[ 0 ] && X_Class_getClass( args[ 0 ] ) ){\r
538                 params.push( args.shift() );\r
539         };\r
540         \r
541         /* props 未定義でも可 */\r
542         params.push( args[ 0 ] );\r
543         \r
544         // 継承クラスの作成\r
545         if( X_Class_useObjectCreate ){\r
546                 X_Class_traits = Object.create( Super.prototype );\r
547         } else\r
548         if( X_Class_use_proto_ ){\r
549                 X_Class_traits = Super.prototype;\r
550         } else {\r
551                 X_Class_traits = new Super( X_Closure_COMMAND_DROP );\r
552         };\r
553         klass  = X_Class_create.apply( X.Class, params );\r
554         X_Class_traits = null;\r
555         \r
556         def    = X_Class_getClassDef( klass );\r
557         // 継承用プロパティを控える\r
558         def.SuperClass       = Super;\r
559         def.SuperProto       = Super.prototype;\r
560         def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
561         \r
562         return klass;\r
563 };\r
564         \r
565 /*\r
566  * new の実体.コンストラクタの機能は instance.Constructor に書く.\r
567  * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる\r
568  */\r
569 function X_Class_actualConstructor( f, args ){\r
570         var klass    = f.klass,\r
571                 def      = f.classDef,\r
572                 instance, obj;\r
573 \r
574         if( def.isAbstract ){\r
575                 X.Logger.critical( 'AbstractClass!' );\r
576                 return;\r
577         };\r
578         \r
579         instance = def.pool && def.pool.length ?\r
580                                         def.pool.pop() :\r
581                                 X_Class_useObjectCreate ?\r
582                                         Object.create( klass.prototype ) :\r
583                                         new klass( X_Closure_COMMAND_DROP );\r
584         \r
585         def.live && def.live.push( instance );\r
586 \r
587         obj = def.Constructor ?\r
588                         def.Constructor.apply( instance, args ) :\r
589                 def.SuperConstructor &&\r
590                         def.SuperConstructor.apply( instance, args );\r
591 \r
592         if( obj !== instance && ( X_Type_isObject( obj ) || X_Type_isFunction( obj ) ) ){ // Class\r
593                 instance[ 'kill' ]();\r
594                 return obj;\r
595         };\r
596         return instance;\r
597 };\r
598 \r
599 console.log( 'X.Core.Class' );\r