OSDN Git Service

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