OSDN Git Service

Version 0.6.179, fix X.Audio & X.AudioSprite.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 04_XObject.js
index 3e57b52..329973d 100644 (file)
-\r
-var X_Object_inObject = X.UA.IE < 5.5 ? // TODO JScript で判定\r
-       (function( name, obj ){\r
-               var p;\r
-               if( obj[ name ] ) return true;\r
+/**\r
+ * name in object 構文が使えない環境で構文解析エラーを回避するためにこのメソッドを使用します。\r
+ * 但し for( name in object ) については構文解析エラーになる環境はありません。\r
+ * @alias X.Object.inObject\r
+ * @function\r
+ * @param {string|number} name \r
+ * @param {object} obj \r
+ * @return {boolean} name が定義されている(値が undefined や null でも) -> true\r
+ */\r
+var X_Object_inObject = !X_Script_gte15 ? // TODO JScript で判定\r
+       (function( name, obj, _ ){\r
                name += ''; // 数値も許可\r
-               for( p in obj ){\r
-                       if( p === name ) return true;\r
+               if( obj[ name ] ) return true; // quick\r
+               for( _ in obj ){\r
+                       if( _ === name ) return true;\r
                };\r
                return false;\r
        }) :\r
-       new Function( 'a,b', 'return a in b' );// なぜか ie5 でもerror\r
+       new Function( 'a,b', 'return (""+a) in b' );\r
+\r
 \r
+// ------------------------------------------------------------------------- //\r
+// --- interface ----------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
 \r
-X.Object = {\r
+/**\r
+ * Object に関する関数を集めたものです。\r
+ * @namespace X.Object\r
+ * @alias X.Object\r
+ */\r
+X[ 'Object' ] = {\r
+\r
+       'copy'       : X_Object_copy,\r
        \r
-       clone      : X_Object_clone,\r
+       'deepCopy'   : X_Object_deepCopy,\r
        \r
-       deepCopy   : X_Object_deepCopy,\r
+       'override'   : X_Object_override,\r
        \r
-       cloneArray : X_Object_cloneArray,\r
+       'clear'      : X_Object_clear,\r
        \r
-       isEmpty    : X_Object_isEmpty,\r
+       'isEmpty'    : X_Object_isEmpty,\r
        \r
-       inObject   : X_Object_inObject\r
-};\r
+       'inObject'   : X_Object_inObject,\r
        \r
-function X_Object_clone( src ){\r
+       'find'       : X_Object_find\r
+       // TODO hasOwnProperty\r
+};\r
+\r
+// ------------------------------------------------------------------------- //\r
+// --- implements ---------------------------------------------------------- //\r
+// ------------------------------------------------------------------------- //\r
+/**\r
+ * 単純なクローンでメンバーをコピーしたオブジェクトを返します。 k in null でエラーになる Opera7- に対策済。\r
+ * @alias X.Object.copy\r
+ * @param {object|Array} src コピー元のオブジェクトです。\r
+ * @return {object|Array}\r
+ */\r
+function X_Object_copy( src ){\r
        var ret, k;\r
-       if( typeof src !== 'object' ) return src;\r
+       \r
+       if( !src || !X_Type_isObject( src ) ) return src;\r
+       \r
        ret = {};\r
        for( k in src ){\r
+               //if( X_EMPTY_OBJECT[ k ] ) continue;\r
                ret[ k ] = src[ k ];\r
        };\r
        return ret;\r
 };\r
 \r
+/**\r
+ * オブジェクトにオブジェトのメンバーをコピーします。同じ名前のメンバーは上書きされます。\r
+ * @alias X.Object.override\r
+ * @param {object} target コピーされるオブジェクトです。返り値はこのオブジェクトです。\r
+ * @param {object} src コピー元のオブジェクトです。\r
+ * @return {object} target が返る。\r
+ */\r
+function X_Object_override( target, src ){\r
+       var k;\r
+       if( !src || !X_Type_isObject( src ) ) return target;\r
+       for( k in src ){\r
+               //if( X_EMPTY_OBJECT[ k ] ) continue;\r
+               target[ k ] = src[ k ];\r
+       };\r
+       return target;\r
+};\r
+\r
+/**\r
+ * オブジェクトの全てのメンバーを破棄します。\r
+ * @alias X.Object.clear\r
+ * @param {object} obj。\r
+ */\r
+function X_Object_clear( obj, k ){\r
+       if( obj ){\r
+               for( k in obj ){\r
+                       delete obj[ k ];\r
+               };\r
+       };\r
+};\r
+\r
+\r
+/**\r
+ * オブジェクト(object, Array)のメンバーを探索して、ディープコピーしたオブジェクトを返します。\r
+ * オブジェクトが循環参照している場合は、既にコピーしているオブジェクトが現れた時点で、先に作成しているコピーの参照を返すので無限にループすることはありません。\r
+ * @alias X.Object.deepCopy\r
+ * @param {object|Array} src コピー元のオブジェクトです。\r
+ * @return {object|Array}\r
+ */\r
 function X_Object_deepCopy( src ){             \r
        return X_Object_deepCopy_( src, [], [], -1 );\r
 };\r
 \r
-function X_Object_deepCopy_( src, objSrc, objCopy, n ) {\r
-       var ret, i, key;\r
+function X_Object_deepCopy_( src, objSrc, objCopy, n ){\r
+       var ret, i, k;\r
+       \r
        if( !src ){ // 0, "", null, undefined, NaN, false\r
                return src;\r
        } else\r
-       if( X.Type.isArray( src ) ){\r
+       if( X_Type_isArray( src ) ){\r
                i = objSrc.indexOf( src );\r
                if( i !== -1 ) return objCopy[ i ];\r
                objSrc[ ++n ] = src;\r
                objCopy[ n ]  = ret = [];\r
        } else\r
-       if( X.Type.isObject( src ) ){\r
+       if( X_Type_isObject( src ) ){\r
                i = objSrc.indexOf( src );\r
                if( i !== -1 ) return objCopy[ i ];\r
                objSrc[ ++n ] = src;\r
@@ -59,34 +131,125 @@ function X_Object_deepCopy_( src, objSrc, objCopy, n ) {
                // string, number, true\r
                return src;\r
        };\r
-       for( key in src ){\r
-               ret[ key ] = clone( src[ key ], objSrc, objCopy, n );\r
+       for( k in src ){\r
+               //if( X_EMPTY_OBJECT[ k ] ) continue;\r
+               ret[ k ] = X_Object_deepCopy_( src[ k ], objSrc, objCopy, n );\r
        };\r
        return ret;\r
 };\r
 \r
-function X_Object_cloneArray( ary ){\r
-       var ret = [], i = ary.length;\r
-       if( !i ) return ret;\r
-       for( ; i; ){\r
-               ret[ --i ] = ary[ i ];\r
-       };\r
-       return ret;\r
-};\r
-       \r
+/**\r
+ * object が空か?調べます。 object でない場合、undefined が返る\r
+ * @alias X.Object.isEmpty\r
+ * @param {object} v \r
+ * @return {boolean|undefined}\r
+ */\r
 function X_Object_isEmpty( v ){\r
-       var p;\r
-       for( p in v ){\r
+       if( !v ) return;\r
+       for( var k in v ){\r
+               //if( X_EMPTY_OBJECT[ _k ] ) continue;\r
                return false;//if( v.hasOwnProperty && v.hasOwnProperty( p ) ) return false; ie4 で動かない、、、\r
        };\r
        return true;\r
 };\r
 \r
-/*     \r
-X.matchTest = function( array1, array2 ){\r
-       var i = array2.length;\r
-       for( ; i; ){\r
-               if( array1.indexOf( array2[ --i ] ) === -1 ) return false;\r
+/**\r
+ * obj に対し、selector で示した値を返す。メンバを辿れなかった場合、undefined が返る。\r
+ * @alias X.Object.find\r
+ * @param {object} obj\r
+ * @param {string} selector\r
+ * @return {*}\r
+ */\r
+function X_Object_find( obj, selector ){\r
+       var selectors = selector.split( '>' );\r
+       \r
+       for( ; selector = selectors.shift(); ){\r
+               obj = obj[ selector ];\r
+               if( !obj ) return;\r
        };\r
-       return true;\r
-}; */\r
+       return obj;\r
+};\r
+\r
+// TODO X.Object.own( obj, name )\r
+/*\r
+ * Safari の JavaScript の不備 \r
+ * http://nanto.asablo.jp/blog/2006/01/13/209495\r
+ * \r
+ * web.paulownia.jp - JavaScriptとクロージャ\r
+ * https://web.archive.org/web/20070526063400/http://web.paulownia.jp/script/oop/closure.html\r
+ * MacOSX 10.3のsafariにはhasOwnPropertyが実装されていないので、独自に追加する必要があります。\r
+ * \r
+ * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法\r
+ * http://os0x.hatenablog.com/entry/20080901/1220272509\r
+ */\r
+/*\r
+Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
+               var proto = this.constructor && this.constructor.prototype,\r
+                       __p__ = proto && proto.__proto__,\r
+                       v     = this[ p ],\r
+                       r     = false;\r
+               \r
+               if( __p__ ) proto.__proto__ = null;\r
+               \r
+               if( p in this ){\r
+                       if( v !== v ){\r
+                               if( proto && ( p in proto ) && proto[ p ] !== proto[ p ] ){ // proto[ p ] is NaN\r
+                                       proto[ p ] = 0; // different value\r
+                                       r = this[ p ] !== this[ p ]; // isNaN?\r
+                                       proto[ p ] = v; // set NaN\r
+                               } else {\r
+                                       r = true;\r
+                               };\r
+                       } else\r
+                       if( proto && p in proto && proto[ p ] === v ){\r
+                               // this と proto に同名で同値が書かれている可能性あり\r
+                               proto[ p ] = v + ' '; // different value\r
+                               r = v === this[ p ];\r
+                               proto[ p ] = v;\r
+                       } else {\r
+                               r = true;\r
+                       };\r
+               };\r
+               \r
+               if( __p__ ) proto.__proto__ = __p__;\r
+               \r
+               return r;\r
+  }); */\r
+/*\r
+Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
+               var proto = this.constructor && this.constructor.prototype,\r
+                       __p__ = proto && proto.__proto__,\r
+                       r     = false,//!!( __p__ && ( proto.__proto__ = null ) )\r
+                       _pro_, v, isNaN;\r
+               \r
+               if( __p__ ) proto.__proto__ = null;\r
+               if( this.__proto__ ){\r
+                       _pro_ = this.__proto__;\r
+                       this.__proto__ = null;\r
+               };\r
+               \r
+               if( p === '__proto__' ){\r
+                       r = !!_pro_;\r
+               } else {\r
+                       v     = this[ p ];\r
+                       isNaN = v !== v;                \r
+                       \r
+                       if( p in this ){\r
+                               if( proto && p in proto && ( proto[ p ] === v ) ^ isNaN ){ //true + false, false + true\r
+                                       // this と proto に同名で同値が書かれている可能性あり\r
+                                       proto[ p ] = v + ' '; // different value\r
+                                       r = ( v === this[ p ] ) ^ isNaN; // true + false, false + true\r
+                                       proto[ p ] = v;\r
+                               } else {\r
+                                       r = true;\r
+                               };\r
+                       };                      \r
+               };\r
+\r
+               if( __p__ ) proto.__proto__ = __p__;\r
+               if( _p_ ) this.__proto__ = _pro_;\r
+               return r;\r
+  }); */\r
\r
\r
+\r