*/\r
// TODO kill したインスタンスのイベントが残っていないか?これは開発用のみ\r
'kill' : function(){\r
- var listeners, flag, p, timers, def;\r
+ var listeners, flag, p, i, list, timers, def;\r
\r
// TODO 破棄済のインスタンスへの kill\r
\r
// listeners がない場合、イベントの登録がないため、BEFORE_KILL_INSTANCE は呼ばれない。\r
// KILL_RESERVED == true の場合、BEFORE_KILL_INSTANCE は呼ばれない。\r
if( listeners && !listeners[ X_LISTENERS_KILL_RESERVED ] && listeners[ X_EVENT_BEFORE_KILL_INSTANCE ] ){\r
- X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this;\r
+ X_Class_SEAL_KILLING[ i = X_Class_SEAL_KILLING.length ] = this;\r
\r
if( this[ 'dispatch' ]( X_EVENT_BEFORE_KILL_INSTANCE ) & X_CALLBACK_PREVENT_DEFAULT ){\r
this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE_CANCELED );\r
\r
X_Class_SEAL_KILLING.length === 1 ?\r
( X_Class_SEAL_KILLING.length = 0 ) :\r
- X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
+ X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING[ i ] === this ? i : X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
\r
if( flag ) return;\r
};\r
};\r
\r
if( listeners[ X_EVENT_KILL_INSTANCE ] ){\r
- X_Class_SEAL_KILLING[ X_Class_SEAL_KILLING.length ] = this;\r
+ X_Class_SEAL_KILLING[ i = X_Class_SEAL_KILLING.length ] = this;\r
\r
listeners[ X_LISTENERS_KILL_RESERVED ] = false; \r
this[ 'dispatch' ]( X_EVENT_KILL_INSTANCE );\r
\r
X_Class_SEAL_KILLING.length === 1 ?\r
( X_Class_SEAL_KILLING.length = 0 ) :\r
- X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
+ X_Class_SEAL_KILLING.splice( X_Class_SEAL_KILLING[ i ] === this ? i : X_Class_SEAL_KILLING.indexOf( this ), 1 );\r
+ };\r
+\r
+ if( !( listeners = this[ '_listeners' ] ) ){\r
+ for( p in listeners ){\r
+ //if( X_EMPTY_OBJECT[ opt_type ] ) continue;\r
+ if( p <= X_LISTENERS_KILL_RESERVED ) continue;\r
+ list = listeners[ p ];\r
+ for( i = list.length; i; ){\r
+ this[ 'unlisten' ]( p, list[ --i ] );\r
+ };\r
+ }; \r
};\r
- \r
- X_EventDispatcher_unlistenAll( this );\r
};\r
\r
if( this[ 'instanceOf' ]( Node ) ){\r
},\r
\r
/**\r
- * 関数は Constructor 内で使用します。クラス定義を辿ってスーパークラスのコンストラクタを探します。<br>\r
+ * 関数は Constructor 内で使用します。クラス定義を辿ってスーパークラスのコンストラクタを呼び出します。<br>\r
* 内部的には、呼び出したコンストラクタは配列に控え(X_Class_CALLING_SUPER)、呼び出したコンストラクタ内でさらに Super が呼ばれた場合、配列を元にさらにスーパーなコンストラクタを辿ります。\r
* @example Constructor : function( arg1, arg2 ){\r
* this.Super( aeg1, arg2 );\r
// TODO 現在 new しているインスタンスを保持してチェックする\r
'Super' : function( var_args ){\r
var me = this,\r
- sClass = me,\r
+ sClass = me.constructor,\r
i = X_Class_SUPER_CALLER.indexOf( me ),\r
stack, t, def, ret;\r
\r
if( i === -1 ){\r
X_Class_SUPER_CALLER[ i = X_Class_SUPER_CALLER.length ] = me;\r
- X_Class_SUPER_STACKS[ i ] = stack = 0;\r
+ t = stack = X_Class_SUPER_STACKS[ i ] = 0;\r
} else {\r
- stack = X_Class_SUPER_STACKS[ i ];\r
+ t = stack = X_Class_SUPER_STACKS[ i ];\r
+ \r
+ while( t ){\r
+ sClass = X_Class_getClassDef( sClass ).SuperClass;\r
+ --t;\r
+ }; \r
};\r
- \r
- t = stack;\r
- \r
- while( t ){\r
- sClass = X_Class_getClassDef( sClass ).SuperClass;\r
- --t;\r
- };\r
- \r
+\r
while( sClass ){\r
++t;\r
sClass = X_Class_getClassDef( sClass ).SuperClass;\r
};\r
};\r
\r
+ // index が替わっている可能性があるので取り直し\r
+ if( X_Class_SUPER_CALLER[ i ] !== me ) i = X_Class_SUPER_CALLER.indexOf( me );\r
+ \r
if( X_Class_SUPER_STACKS[ i ] === stack ) console.log( 'スーパークラス、またはスーパークラスのコンストラクタは存在しません' );\r
\r
if( stack === 0 ){\r
},\r
\r
/**\r
- * func について、親クラスで設定されている同名の関数メンバーを呼び出す。<br>\r
- * 第一引数にオーバーライド済の自身の(自身から参照できる)関数を指定します。内部では関数名を調べた上で prototype チェーンをゴリゴリ辿る、特別なことはしていません。\r
- * superCall がネストする場合、arguments.callee でないと正しく現在階層を取得して親関数を知ることができない\r
- * 次の理由によって、関数名で辿ることはやめました\r
+ * myFunc について、スーパークラスで設定されている同名の関数を呼び出す。<br>\r
+ * 低速な関数なので多用されるべきではありません!<br>\r
+ * 第一引数に自身の(自身から参照できる)関数を指定します。内部では関数名を調べた上で prototype チェーンをゴリゴリ辿る、特別なことはしていません。<br>\r
+ * superCall と Super がネストする場合も現在のクラス階層を X_Class_SUPER_CALLER, X_Class_SUPER_STACKS を使って控えているので、意図した親関数が呼ばれます。<br>\r
+ * 次の理由によって、関数名で辿ることは非推奨です。\r
* <ol>\r
* <li>closur compiler でメソッド名が変更される\r
- * <li>superCall 内からさらに superCall が呼ばれた場合に、起点となる関数を特定できない\r
* </ol>\r
- * 次の場合、意図した動作が得られません\r
+ * 次の場合、意図した動作が得られません。\r
* <ol>\r
- * <li>2つ以上の異なる名前で同じ関数がメンバーがいた場合<br>\r
- * <li>または、サブクラスのメンバーにスーパークラスと同じ関数が出現する\r
- * <li>superCall 以外の手段で親関数を呼び、そのなかで superCall を読んだ\r
+ * <li>2つ以上の異なる名前で同じ関数がメンバーがいた場合\r
+ * <li>サブクラスの prototype にスーパークラスと同じ関数をコピーしている\r
+ * <li>非関数でメンバーを上書きしている\r
+ * <li>superCall 以外の手段で親関数を呼び、そのなかで superCall を呼んだ\r
* </ol>\r
- * 通常の X.Class.create の書き方ではこのような状況は起きませんが、js はなんでもできるので\r
- * 参考:<a href="http://qiita.com/no22@github/items/d3bead2acbb7ff1fb86b" target="_blank">ES5なJavascriptでモダンなクラス的継承&スーパー呼び出し </a>\r
+ * 通常の X.Class.create の書き方ではこのような状況は起きませんが、js はなんでもいろいろ出来てしまいますから…<br>\r
+ * 参考:<a href="http://qiita.com/no22@github/items/d3bead2acbb7ff1fb86b" target="_blank">ES5なJavascriptでモダンなクラス的継承&スーパー呼び出し </a><br>\r
+ * original:<a href="http://javascript.crockford.com/inheritance.html" target="_blank">Classical Inheritance in JavaScript</a>\r
* @param myFunc {Function|string} オーバーライド済の自身の(自身から参照できる)関数。\r
* @param var_args {...*} オーバーライド元関数に渡す任意の数の引数\r
- * @example return this.superCall( arguments.callee, param0, param1, ... );\r
+ * @example return this.superCall( this.myFunc, param0, param1, ... );\r
* @return {*} オーバーライド元の関数を呼び出した戻り値。\r
*/\r
'superCall' : function( myFunc, var_args ){\r
sClass = me.constructor,\r
proto = sClass.prototype,\r
i = X_Class_SUPER_CALLER.indexOf( me ),\r
- l, d, ret,\r
args = arguments,\r
- name, p, sFunc;\r
+ p, name, t, sFunc, ret;\r
\r
if( X_Type_isFunction( myFunc ) ){\r
for( p in proto ){\r
};\r
};\r
if( !name ) return;\r
+ } else\r
+ if( X_Type_isString( myFunc ) && X_Type_isFunction( me[ myFunc ] ) ){\r
+ name = myFunc;\r
} else {\r
return;\r
};\r
\r
if( i === -1 ){\r
X_Class_SUPER_CALLER[ i = X_Class_SUPER_CALLER.length ] = me;\r
- X_Class_SUPER_STACKS[ i ] = stack = 0;\r
+ t = stack = X_Class_SUPER_STACKS[ i ] = 0;\r
} else {\r
- stack = X_Class_SUPER_STACKS[ i ];\r
+ t = stack = X_Class_SUPER_STACKS[ i ];\r
+ \r
+ while( t ){\r
+ sClass = X_Class_getClassDef( sClass ).SuperClass;\r
+ --t;\r
+ }; \r
};\r
\r
- t = stack;\r
-\r
- while( t ){\r
- sClass = X_Class_getClassDef( sClass ).SuperClass;\r
- --t;\r
- };\r
- \r
if( sClass ){\r
myFunc = sClass.prototype[ name ];\r
\r
sFunc = sClass.prototype[ name ];\r
\r
if( sFunc !== myFunc /* X_Object_own( name, sClass.prototype ) */ ){\r
- // this の関数と異なり、値が設定されていたら、今は手を抜いて undef か?見ている、正しくは hasOwnProperty\r
if( X_Type_isFunction( sFunc ) ){\r
X_Class_SUPER_STACKS[ i ] += t;\r
switch( args.length ){\r
- case 0 :\r
- ret = sFunc.call( me );\r
- break;\r
case 1 :\r
- ret = sFunc.call( me, args[ 0 ] );\r
+ ret = sFunc.call( me );\r
break;\r
case 2 :\r
- ret = sFunc.call( me, args[ 0 ], args[ 1 ] );\r
+ ret = sFunc.call( me, args[ 1 ] );\r
break;\r
case 3 :\r
- ret = sFunc.call( me, args[ 0 ], args[ 1 ], args[ 2 ] );\r
+ ret = sFunc.call( me, args[ 1 ], args[ 2 ] );\r
+ break;\r
+ case 4 :\r
+ ret = sFunc.call( me, args[ 1 ], args[ 2 ], args[ 3 ] );\r
break;\r
default :\r
args = X_Array_copy( args );\r
};\r
};\r
\r
+ // index が替わっている可能性があるので取り直し\r
+ if( X_Class_SUPER_CALLER[ i ] !== me ) i = X_Class_SUPER_CALLER.indexOf( me );\r
+\r
if( stack === 0 ){\r
X_Class_SUPER_CALLER.splice( i, 1 );\r
X_Class_SUPER_STACKS.splice( i, 1 );\r
// --- interface ----------------------------------------------------------- //\r
// ------------------------------------------------------------------------- //\r
\r
-/**\r
+/*\r
* @enum {number}\r
* @const\r
*/\r