OSDN Git Service

248b5bd16cb622b820df2f831241e38bac20178a
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 11_XClass.js
1 /**\r
2  * Class を定義し システムの管理下に置く.\r
3  * 全てのクラスと pool が有効の場合インスタンスへの参照が保持される.\r
4  *  1. X.Class.create( opt_settings, opt_name, opt_privateClass, opt_props ) でクラスを登録.\r
5  *  2. コンストラクタ となるメソッドは、opt_props 内の Constructor : function( arg ){ ... }, に書く.\r
6  *  3. 通常通り new で インスタンス生成\r
7  *  4. kill() でオブジェクトをクリーンして削除、pool が有効の場合は pool される.\r
8  *  5. pool が有効の場合、new で pool されたインスタンスが返される.\r
9  *  6. \r
10  * \r
11  */\r
12 \r
13 // ------------------------------------------------------------------------- //\r
14 // ------------ local variables -------------------------------------------- //\r
15 // ------------------------------------------------------------------------- //\r
16 var X_Class_CLASS_LIST         = [],\r
17         X_Class_DEF_LIST           = [],\r
18         X_Class_PRIVATE_CLASS_LIST = [],\r
19         X_Class_PRIVATE_DEF_LIST   = [],\r
20         X_Class_CALLING_SUPER      = [],\r
21         X_Class_CALL_SUPER_STACK   = [],\r
22         X_Class_killPrivateFlag    = false,\r
23         X_Class_traits             = null,\r
24         X_Class_useObjectCreate    = false, // !!Object.create, http://jsperf.com/prototype-vs-object-create-perf\r
25         X_Class_use_proto_         = !X_UA.OperaMobile && !X_UA.OperaTablet && !!X.emptyFunction.prototype.__proto__,\r
26                 // Opera Mobile 12.10 Android11 IS01 でクラスのメンバが欠落する問題に遭遇。__proto__ を使わないと動作,,,\r
27 \r
28 /** \r
29  * X.Class.create で定義されたクラスのインスタンスが共通で備えるメソッド を格納\r
30  *\r
31  * @class\r
32  */ \r
33 X_Class_CommonProps =\r
34 \r
35 {\r
36         /*\r
37          * インスタンスの破棄。\r
38          * TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ\r
39          */\r
40         kill : function(){\r
41                 var instance = this,\r
42                         klass    = X_Class_getClass( instance ),\r
43                         def      = X_Class_getClassDef( klass ),\r
44                         data, p, i;\r
45                 if( def.isPrivate && !X_Class_killPrivateFlag ){\r
46                         X.Logger.critical( 'PrivateInstance.kill() work in PrivateUser.kill().' );\r
47                         return;\r
48                 };\r
49                 X_Class_killPrivateFlag = false; // instance.kill() 内で PrivateInstance.kill() を防ぐため\r
50                 \r
51                 // X.EventDispatcher とそのサブクラスは kill() が呼ばれた通知を発行する。\r
52                 // X.Event.BEFORE_KILL_INSTANCE はキャンセル可能(private な class は不可)\r
53                 // X.Event.KILL_INSTANCE は、プロパティやイベントリスナの削除直前に発行\r
54                 // X.Event.KILL_INSTANCE_CANCELED は kill() がキャンセルされた場合に発行。また dispatchループ中にkill()が呼ばれると一旦キャンセルされ発行。\r
55                 //   (flagを立ててdispatchの終わりにkillする)\r
56                 if( this.instanceOf( X.EventDispatcher ) ){\r
57                         if( !def.isPrivate ){\r
58                                 if( this[ '_listeners' ] && this[ '_listeners' ]._dispatching ){\r
59                                         this.dispatch( X.Event.BEFORE_KILL_INSTANCE );\r
60                                         this[ '_listeners' ]._killReserved = true;\r
61                                         this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
62                                         return;\r
63                                 } else\r
64                                 if( this.dispatch( X.Event.BEFORE_KILL_INSTANCE ) & X.Callback.PREVENT_DEFAULT ){\r
65                                         this.dispatch( X.Event.KILL_INSTANCE_CANCELED );\r
66                                         return;\r
67                                 };\r
68                         } else {\r
69                                 this.dispatch( X.Event.BEFORE_KILL_INSTANCE );  \r
70                         };\r
71                         this.dispatch( X.Event.KILL_INSTANCE );\r
72                         this._listeners && X_EventDispatcher_systemUnlisten( this ); //.unlisten();\r
73                 };\r
74                 \r
75                 for( p in instance ){\r
76                         if( instance.hasOwnProperty && !instance.hasOwnProperty( p ) ) continue;\r
77                         delete instance[ p ];\r
78                 };\r
79                 if( def.pool ){\r
80                         def.live && def.live.splice( def.live.indexOf( instance ), 1 );\r
81                         def.pool[ def.pool.length ] = instance;\r
82                 };\r
83                 if( def.privateClass ){\r
84                         i = def.userList.indexOf( instance );\r
85                         if( i !== -1 ){\r
86                                 data = X_Class_getPrivate( instance );\r
87                                 X_Class_killPrivateFlag = true;\r
88                                 if( data[ '_listeners' ] && data[ '_listeners' ]._dispatching && data.instanceOf( X.EventDispatcher ) ){\r
89                                         data[ '_listeners' ]._killReserved = true;\r
90                                 } else {\r
91                                         data.kill();\r
92                                 };\r
93                                 def.dataList.splice( i, 1 );\r
94                                 def.userList.splice( i, 1 );\r
95                         };\r
96                 };\r
97         },\r
98         \r
99         /*  クラス定義を辿ってスーパークラスのコンストラクタを探す。\r
100          *  呼び出したコンストラクタは配列に控える。\r
101          *  さらに呼ばれた場合、配列を元にさらに奥のコンストラクタを取得\r
102          *  TODO 現在 new しているインスタンスを保持してチェックする\r
103          */\r
104         Super : function(){\r
105                 var sClass = this,\r
106                         i      = X_Class_CALLING_SUPER.indexOf( sClass ),\r
107                         n      = -1,\r
108                         l, sList, def, sConst, ret;\r
109         \r
110                 if( i === -1 ){\r
111                         X_Class_CALLING_SUPER[ l = X_Class_CALLING_SUPER.length ] = sClass;\r
112                         X_Class_CALL_SUPER_STACK[ l ] = sList = [];\r
113                 } else {\r
114                         sList = X_Class_CALL_SUPER_STACK[ i ];\r
115                 };\r
116                 \r
117                 while( sClass ){\r
118                         def    = X_Class_getClassDef( sClass );\r
119                         sClass = def.SuperClass;\r
120                         sConst = def.SuperConstructor;\r
121                         if( sConst && sList[ ++n ] !== sConst ){\r
122                                 sList[ n ] = sConst;\r
123                                 ret = sConst.apply( this, arguments );\r
124                                 --sList.length;\r
125                                 if( !sList.length ){\r
126                                         X_Class_CALLING_SUPER.splice( i, 1 );\r
127                                         X_Class_CALL_SUPER_STACK.splice( i, 1 );\r
128                                 };\r
129                                 return ret;\r
130                         };\r
131                 };\r
132                 console.log( 'スーパークラスのコンストラクタが見つかりません' );\r
133         },\r
134 \r
135         /*\r
136          * func について、親クラスで設定されている同名の関数メンバーを呼び出す\r
137          * 2つ以上の異なる名前で同じ関数がメンバーだった場合、失敗します\r
138          * 例) this.superCall( arguments.callee, param0, param1, ... )\r
139          */\r
140         superCall : function( func /* ...args */ ){\r
141                 var sClass = this,\r
142                         args   = arguments,\r
143                         name, p, sFunc, hit = false;\r
144                 if( X.Type.isFunction( func ) ){\r
145                         for( p in this ){\r
146                                 if( this[ p ] === func ){\r
147                                         name = p;\r
148                                         break;\r
149                                 };\r
150                         };\r
151                         if( !name ) return;\r
152                 } else {\r
153                         return;\r
154                 };\r
155                 \r
156                 if( X_EMPTY_OBJECT[ name ] ) return;\r
157                 \r
158                 while( sClass ){\r
159                         def    = X_Class_getClassDef( sClass );\r
160                         sClass = def.SuperClass;\r
161                         sFunc  = sClass.prototype[ name ];\r
162                         if( sFunc === func ){\r
163                                 hit = true; // 現在の関数にヒット\r
164                         } else\r
165                         if( hit && X_Object_inObject( name, this ) ){\r
166                                 if( X.Type.isFunction( sFunc ) ){\r
167                                         switch( args.length ){\r
168                                                 case 1 :\r
169                                                         return sFunc.call( this );\r
170                                                 case 2 :\r
171                                                         return sFunc.call( this, args[ 1 ] );\r
172                                                 case 3 :\r
173                                                         return sFunc.call( this, args[ 1 ], args[ 2 ] );\r
174                                                 case 4 :\r
175                                                         return sFunc.call( this, args[ 1 ], args[ 2 ], args[ 3 ] );\r
176                                                 default :\r
177                                                         args = X.Object.cloneArray( args );\r
178                                                         args.shift();\r
179                                                         return sFunc.apply( this, args );\r
180                                         };\r
181                                 };\r
182                                 break;\r
183                         };\r
184                 };\r
185         },\r
186         \r
187         /*\r
188          * TODO instanceof に対応したブラウザはそちらを使用\r
189          */\r
190         instanceOf : function( klass ){\r
191                 var Super = this;\r
192                 if( this.constructor === klass ) return true;\r
193                 while( Super = X_Class_getClassDef( Super ).SuperClass ){\r
194                         if( Super === klass ) return true;\r
195                 };\r
196                 return false;\r
197         }\r
198 };\r
199 \r
200 // ------------------------------------------------------------------------- //\r
201 // --- interface ----------------------------------------------------------- //\r
202 // ------------------------------------------------------------------------- //\r
203 \r
204 /** @namespace */ \r
205 X.Class = {\r
206         \r
207         NONE         : 0,\r
208         \r
209     /**\r
210      * インスタンスは破棄時(this.kill())に回収され、次回の new MyClass() 時に再利用されます。\r
211      * @memberof X.Class */\r
212         POOL_OBJECT  :  1,\r
213         \r
214         /**\r
215          * 定義するクラスは抽象クラスになります。new AbstractClass() とするとエラーになります。\r
216          * @memberof X.Class */\r
217         ABSTRACT     :  2,\r
218         \r
219         \r
220         /** @memberof X.Class */\r
221         FINAL        :  4,\r
222         /** @memberof X.Class */\r
223         SUPER_ACCESS :  8,\r
224         /** @memberof X.Class */\r
225         PRIVATE_DATA : 16,\r
226         /** @memberof X.Class */\r
227         SINGLETON    : 32, // 未実装\r
228         \r
229         create : function( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
230                 var args        = X_Object_cloneArray( arguments ),\r
231                         displayName = args[ 0 ],\r
232                         classSetting,\r
233                         opt_pool, opt_abstract, opt_final, opt_private,\r
234                         privateDef,\r
235                         props,\r
236                         klass,\r
237                         classDef = {}, hash;\r
238                 if( X.Type.isString( displayName ) === true ){\r
239                         classDef.displayName = displayName;\r
240                         args.shift();\r
241                 };\r
242                 \r
243                 // クラス設定\r
244                 classDef.setting = classSetting = args[ 0 ];\r
245                 if( X.Type.isNumber( classSetting ) ){\r
246                         opt_pool     = !!( classSetting & X.Class.POOL_OBJECT  );\r
247                         opt_abstract = !!( classSetting & X.Class.ABSTRACT     );\r
248                         opt_final    = !!( classSetting & X.Class.FINAL        );\r
249                         opt_private  = !!( classSetting & X.Class.PRIVATE_DATA );\r
250                         if( opt_final && opt_abstract ){\r
251                                 X.Logger.critical( 'final & Abstract!' );\r
252                                 return;\r
253                         };      \r
254                         args.shift();\r
255                 } else {\r
256                         classDef.setting = 0;\r
257                 };\r
258                 \r
259                 // シャドウクラス\r
260                 if( X_Class_PRIVATE_CLASS_LIST.indexOf( args[ 0 ] ) !== -1 ){\r
261                         privateDef = X_Class_getClassDef( args[ 0 ] );\r
262                         if( privateDef.isPrivate !== true ){\r
263                                 X.Logger.critical( 'PrivateClass not found! please, X.Class.create( X.Class.PRIVATE, {...} ).' );\r
264                                 return;\r
265                         } else\r
266                         if( privateDef.Abstract === true ){\r
267                                 X.Logger.critical( 'PrivateClass is Abstract!' );\r
268                                 return;\r
269                         };\r
270                         classDef.privateClass = args.shift();\r
271                 };\r
272                 \r
273                 // インスタンスのメンバー\r
274                 props = args[ 0 ];\r
275                 if( !X.Type.isObject( props ) ){\r
276                         // サブクラスの場合、クラス定義の上書きがなくても作成可能\r
277                         // サブクラスでなくても、クラスメンバ用オブジェクトが無しでも作成可能\r
278                         //if( !X_Class_traits ){\r
279                         //      X.Logger.critical( 'No Class Def!' );\r
280                         //      return;\r
281                         //};\r
282                         props = {};\r
283                 } else\r
284                 if( props.Constructor && X.Type.isFunction( props.Constructor ) ){\r
285                         classDef.Constructor = props.Constructor;\r
286                 };\r
287 \r
288                 klass  = X_Callback_actualClosure( hash = { _ : X_Class_actualConstructor } ); // TODO hash = classDef\r
289                 hash.c = klass;\r
290                 klass.superClassOf = X_Class_superClassOf;\r
291                 klass.subClassOf   = X_Class_subClassOf;\r
292                 \r
293                 if( X_Class_useObjectCreate ){\r
294                         klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonProps, false );\r
295                         klass.prototype.constructor = klass;\r
296                 } else\r
297                 if( X_Class_use_proto_ ){\r
298                         X_Class_override( klass.prototype, props, true );\r
299                         if( X_Class_traits ){\r
300                                 klass.prototype.__proto__ = X_Class_traits;\r
301                         } else {\r
302                                 X_Class_override( klass.prototype, X_Class_CommonProps, false );\r
303                         };\r
304                 } else {\r
305                         klass.prototype = X_Class_override( X_Class_override( X_Class_traits || klass.prototype, props, true ), X_Class_CommonProps, false );\r
306                         klass.prototype.constructor = klass;\r
307                 };\r
308                 klass.name = displayName;\r
309                 \r
310                 if( opt_abstract ){\r
311                         classDef.Abstract = true;\r
312                 } else\r
313                 if( opt_pool ){\r
314                         classDef.pool = [];\r
315                         if( opt_private === false ) classDef.live = [];\r
316                 };                      \r
317                 if( opt_final ){\r
318                         classDef.Final = true;\r
319                 } else {\r
320                         klass.inherits = X_Class_inherits;\r
321                 };                      \r
322                 if( opt_private ){\r
323                         if( classDef.privateClass ){\r
324                                 X.Logger.critical( 'Private Data Class has no PrivateClass!' );\r
325                                 return;\r
326                         };\r
327                         classDef.isPrivate = true;\r
328                         X_Class_PRIVATE_CLASS_LIST.push( klass );\r
329                         X_Class_PRIVATE_DEF_LIST.push( classDef );\r
330                 } else {\r
331                         X_Class_CLASS_LIST.push( klass );\r
332                         X_Class_DEF_LIST.push( classDef );                              \r
333                 };\r
334                 return klass;\r
335         },\r
336         \r
337         _newPrivate  : X_Class_newPrivate,\r
338         \r
339         _getPrivate  : X_Class_getPrivate\r
340         \r
341 };\r
342 \r
343 // ------------------------------------------------------------------------- //\r
344 // --- implements ---------------------------------------------------------- //\r
345 // ------------------------------------------------------------------------- //\r
346 function X_Class_getClass( instance ){\r
347         var cList    = X_Class_CLASS_LIST,\r
348                 i        = cList.length,\r
349                 klass;\r
350         for( ; i; ){\r
351                 klass = cList[ --i ];\r
352                 if( instance.constructor === klass ) return klass;\r
353         };\r
354         cList = X_Class_PRIVATE_CLASS_LIST;\r
355         i     = cList.length;\r
356         for( ; i; ){\r
357                 klass = cList[ --i ];\r
358                 if( instance.constructor === klass ) return klass;\r
359         };\r
360         \r
361         if( cList.indexOf( instance ) !== -1 ) return instance;\r
362         if( X_Class_CLASS_LIST.indexOf( instance ) !== -1 ) return instance;\r
363 };\r
364 \r
365 function X_Class_getClassDef( KlassOrInstance ){\r
366         var i = X_Class_CLASS_LIST.indexOf( KlassOrInstance );\r
367         if( i === -1 ) i = X_Class_CLASS_LIST.indexOf( X_Class_getClass( KlassOrInstance ) );\r
368         if( i !== -1 ) return X_Class_DEF_LIST[ i ];\r
369         \r
370         i = X_Class_PRIVATE_CLASS_LIST.indexOf( KlassOrInstance );\r
371         if( i === -1 ) i = X_Class_PRIVATE_CLASS_LIST.indexOf( X_Class_getClass( KlassOrInstance ) );\r
372         if( i !== -1 ) return X_Class_PRIVATE_DEF_LIST[ i ];\r
373         \r
374         if( X_Class_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
375         if( X_Class_PRIVATE_DEF_LIST.indexOf( KlassOrInstance ) !== -1 ) return KlassOrInstance;\r
376 };\r
377 \r
378 function X_Class_newPrivate( /* instance, args */ ){\r
379         var args         = X_Object_cloneArray( arguments ),\r
380                 user         = args.shift(),\r
381                 def          = X_Class_getClassDef( user ),\r
382                 privateClass = def.privateClass,\r
383                 privateDef   = X_Class_getClassDef( privateClass ),\r
384                 i            = -1;\r
385         if( def.userList ){\r
386                 i = def.userList.indexOf( user );\r
387         } else {\r
388                 def.userList = [];\r
389                 def.dataList = [];\r
390         };\r
391         if( i !== -1 ){\r
392                 X.Logger.critical( 'PrivateData already exist!' );\r
393                 return;\r
394         };\r
395         if( privateDef._tempUser ){\r
396                 X.Logger.critical( 'newPrivate を連続呼び出しされたところ破綻' );\r
397                 return;\r
398         };\r
399         privateDef._tempUser = user;\r
400         return X_Class_actualConstructor( privateClass( X_Closure_COMMAND_BACK ), args );// privateClass.__new( args );\r
401 };\r
402 \r
403 function X_Class_getPrivate( instance ){\r
404         var def = X_Class_getClassDef( instance ),\r
405                 i   = def.userList.indexOf( instance );\r
406         if( i !== -1 ) return def.dataList[ i ];\r
407 };\r
408 \r
409 /* over のプロパティを target にコピーする.ただし target の プロパティが優先, force で解除 */\r
410 function X_Class_override( target, src, force ){\r
411         var p;\r
412         for( p in src ){\r
413                 if( p === 'Constructor' ) continue;\r
414                 if( p === '__proto__' || p === 'prototype' || p === 'constructor' ){\r
415                         X.Logger.critical( p + ' is reserved!' );\r
416                         return;\r
417                 };\r
418                 if( force || target[ p ] === void 0 ){\r
419                         target[ p ] = src[ p ];\r
420                 };\r
421         };\r
422         return target;\r
423 };\r
424 \r
425 function X_Class_superClassOf( klass ){\r
426         var myDef      = X_Class_getClassDef( this ),\r
427                 targetDef  = X_Class_getClassDef( klass ),\r
428                 SuperClass = klass;\r
429 \r
430         if( !myDef || !targetDef || this === klass ) return false;\r
431         \r
432         while( SuperClass = X_Class_getClassDef( SuperClass ).SuperClass ){\r
433                 if( SuperClass === this ) return true;\r
434         };\r
435         \r
436         return false;\r
437 };\r
438 \r
439 function X_Class_subClassOf( klass ){\r
440         return X_Class_superClassOf.call( klass, this );\r
441 };\r
442         \r
443 /* サブクラスを作るメソッド  \r
444  * var subClass = superClass.inherits( ... ) \r
445  * http://d.hatena.ne.jp/m-hiyama/20051018/1129605002\r
446  */\r
447 function X_Class_inherits( /* displayName, classSetting, opt_PrivateClass, props */ ){\r
448         var args        = X_Object_cloneArray( arguments ),\r
449                 params      = [],\r
450                 Super       = this,\r
451                 superDef    = X_Class_getClassDef( Super ),\r
452                 displayName = args[ 0 ],\r
453                 classSetting,\r
454                 //opt_super,\r
455                 klass, def;\r
456         if( superDef.Final ) X.Logger.critical( 'X.Class inherits, Class is final!' );\r
457         \r
458         // サブクラス名\r
459         if( X.Type.isString( displayName ) ){\r
460                 args.shift();\r
461         } else {\r
462                 displayName = 'SubClass of ' + superDef.displayName;\r
463         };\r
464         params.push( displayName );\r
465         \r
466         // サブクラス設定\r
467         classSetting = args[ 0 ];\r
468         if( X.Type.isNumber( classSetting ) ){\r
469                 args.shift();\r
470         } else {\r
471                 // クラス設定がない場合、親からコピーして、Abstract flag は落とす??\r
472                 classSetting = superDef.setting;// &= ~X.Class.ABSTRACT;\r
473         };\r
474         if( superDef.isPrivate ) classSetting = classSetting | X.Class.PRIVATE_DATA;\r
475         //opt_super = !!( classSetting & X.Class.SUPER_ACCESS );\r
476         params.push( classSetting );\r
477 \r
478         // サブクラスのシャドウ\r
479         if( args[ 0 ] && X_Class_getClass( args[ 0 ] ) ){\r
480                 params.push( args.shift() );\r
481         } else\r
482         if( superDef.privateClass ){\r
483                 params.push( superDef.privateClass );\r
484         };\r
485         \r
486         /* props 未定義でも可 */\r
487         params.push( args[ 0 ] );\r
488         \r
489         // 継承クラスの作成\r
490         if( X_Class_useObjectCreate ){\r
491                 X_Class_traits = Object.create( Super.prototype );\r
492         } else\r
493         if( X_Class_use_proto_ ){\r
494                 X_Class_traits = Super.prototype;\r
495         } else {\r
496                 X_Class_traits = new Super( X_Closure_COMMAND_DROP );\r
497         };\r
498         klass  = X.Class.create.apply( X.Class, params );\r
499         X_Class_traits = null;\r
500         \r
501         def    = X_Class_getClassDef( klass );\r
502         // 継承用プロパティを控える\r
503         //if( opt_super === true ){\r
504                 //def.superAccess = true;\r
505                 def.SuperClass  = Super;\r
506                 def.SuperProto  = Super.prototype;\r
507                 def.SuperConstructor = superDef.Constructor || superDef.SuperConstructor;\r
508         // else {\r
509         //      def.SuperClass = Super; // instanceOf() で親クラスを調べる!\r
510         //};\r
511         \r
512         return klass;\r
513 };\r
514         \r
515 /*\r
516  * new の実体.コンストラクタの機能は instance.Constructor に書く.\r
517  * これにより pool された オブジェクト(破棄されたインスタンス) を再利用できる\r
518  */\r
519 function X_Class_actualConstructor( f, args ){\r
520         var klass    = f.c,\r
521                 def      = X_Class_getClassDef( klass ),\r
522                 dataUser = def._tempUser,\r
523                 instance, obj,\r
524                 userDef;\r
525         if( def.Abstract ){\r
526                 X.Logger.critical( 'AbstractClass!' );\r
527                 return;\r
528         };\r
529         if( def.isPrivate && !dataUser ){\r
530                 X.Logger.critical( 'use myClass.newPrivate( instance, ...args )!' );\r
531                 return;\r
532         };\r
533         \r
534         instance = def.pool && def.pool.length > 0 ?\r
535                                         def.pool.pop() :\r
536                                 X_Class_useObjectCreate ?\r
537                                         Object.create( klass.prototype ) :\r
538                                         new klass( X_Closure_COMMAND_DROP );\r
539         \r
540         if( def.isPrivate ){\r
541                 userDef = X_Class_getClassDef( dataUser );\r
542                 userDef.dataList.push( instance );\r
543                 userDef.userList.push( dataUser );\r
544                 instance.User = dataUser;\r
545                 def._tempUser = null;\r
546         } else {\r
547                 def.live && def.live.push( instance );\r
548         };\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         if( ( X.Type.isObject( obj ) && obj !== instance ) || X.Type.isFunction( obj ) ){ // Class\r
555                 instance.kill();\r
556                 return obj;\r
557         };\r
558         return instance;\r
559 };\r
560 \r
561 console.log( 'X.Core.Class' );\r