OSDN Git Service

Fix the bug of X.NodeAnime.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 05_XObject.js
1 /**\r
2  * name in object 構文が使えない環境で構文解析エラーを回避するためにこのメソッドを使用します。\r
3  * 但し for( name in object ) については構文解析エラーになる環境はありません。\r
4  * @alias X.Object.inObject\r
5  * @function\r
6  * @param {string|number} name \r
7  * @param {object} obj \r
8  * @return {boolean} name が定義されている(値が undefined や null でも) -> true\r
9  */\r
10 var X_Object_inObject = !X_Script_gte15 ? // TODO JScript で判定\r
11         (function( name, obj, _ ){\r
12                 name += ''; // 数値も許可\r
13                 if( obj[ name ] ) return true; // quick\r
14                 for( _ in obj ){\r
15                         if( _ === name ) return true;\r
16                 };\r
17                 return false;\r
18         }) :\r
19         new Function( 'a,b', 'return (""+a) in b' );\r
20 \r
21 \r
22 // ------------------------------------------------------------------------- //\r
23 // --- interface ----------------------------------------------------------- //\r
24 // ------------------------------------------------------------------------- //\r
25 \r
26 /**\r
27  * Object に関する関数を集めたものです。\r
28  * @namespace X.Object\r
29  * @alias X.Object\r
30  */\r
31 X[ 'Object' ] = {\r
32 \r
33         'copy'       : X_Object_copy,\r
34         \r
35         'deepCopy'   : X_Object_deepCopy,\r
36         \r
37         'override'   : X_Object_override,\r
38         \r
39         'clear'      : X_Object_clear,\r
40         \r
41         'isEmpty'    : X_Object_isEmpty,\r
42         \r
43         'inObject'   : X_Object_inObject,\r
44         \r
45         'find'       : X_Object_find\r
46         // TODO hasOwnProperty\r
47 };\r
48 \r
49 // ------------------------------------------------------------------------- //\r
50 // --- implements ---------------------------------------------------------- //\r
51 // ------------------------------------------------------------------------- //\r
52 /**\r
53  * 単純なクローンでメンバーをコピーしたオブジェクトを返します。 k in null でエラーになる Opera7- に対策済。\r
54  * @alias X.Object.copy\r
55  * @param {object|Array} src コピー元のオブジェクトです。\r
56  * @return {object|Array}\r
57  */\r
58 function X_Object_copy( src ){\r
59         var ret, k;\r
60         \r
61         if( !src || !X_Type_isObject( src ) ) return src;\r
62         \r
63         ret = {};\r
64         for( k in src ){\r
65                 //if( X_EMPTY_OBJECT[ k ] ) continue;\r
66                 ret[ k ] = src[ k ];\r
67         };\r
68         return ret;\r
69 };\r
70 \r
71 /**\r
72  * オブジェクトにオブジェトのメンバーをコピーします。同じ名前のメンバーは上書きされます。\r
73  * @alias X.Object.override\r
74  * @param {object} target コピーされるオブジェクトです。返り値はこのオブジェクトです。\r
75  * @param {object} src コピー元のオブジェクトです。\r
76  * @return {object} target が返る。\r
77  */\r
78 function X_Object_override( target, src ){\r
79         var k;\r
80         if( !src || !X_Type_isObject( src ) ) return target;\r
81         for( k in src ){\r
82                 //if( X_EMPTY_OBJECT[ k ] ) continue;\r
83                 target[ k ] = src[ k ];\r
84         };\r
85         return target;\r
86 };\r
87 \r
88 /**\r
89  * オブジェクトの全てのメンバーを破棄します。\r
90  * @alias X.Object.clear\r
91  * @param {object} obj\r
92  */\r
93 function X_Object_clear( obj, k ){\r
94         if( obj ){\r
95                 for( k in obj ){\r
96                         delete obj[ k ];\r
97                 };\r
98         };\r
99 };\r
100 \r
101 \r
102 /**\r
103  * オブジェクト(object, Array)のメンバーを探索して、ディープコピーしたオブジェクトを返します。\r
104  * オブジェクトが循環参照している場合は、既にコピーしているオブジェクトが現れた時点で、先に作成しているコピーの参照を返すので無限にループすることはありません。\r
105  * @alias X.Object.deepCopy\r
106  * @param {object|Array} src コピー元のオブジェクトです。\r
107  * @return {object|Array}\r
108  */\r
109 function X_Object_deepCopy( src ){              \r
110         return X_Object_deepCopy_( src, [], [], -1 );\r
111 };\r
112 \r
113 function X_Object_deepCopy_( src, objSrc, objCopy, n ){\r
114         var ret, i, k;\r
115         \r
116         if( !src ){ // 0, "", null, undefined, NaN, false\r
117                 return src;\r
118         } else\r
119         if( X_Type_isArray( src ) ){\r
120                 i = objSrc.indexOf( src );\r
121                 if( i !== -1 ) return objCopy[ i ];\r
122                 objSrc[ ++n ] = src;\r
123                 objCopy[ n ]  = ret = [];\r
124         } else\r
125         if( X_Type_isObject( src ) ){\r
126                 i = objSrc.indexOf( src );\r
127                 if( i !== -1 ) return objCopy[ i ];\r
128                 objSrc[ ++n ] = src;\r
129                 objCopy[ n ]  = ret = {};\r
130         } else {\r
131                 // string, number, true\r
132                 return src;\r
133         };\r
134         for( k in src ){\r
135                 //if( X_EMPTY_OBJECT[ k ] ) continue;\r
136                 ret[ k ] = X_Object_deepCopy_( src[ k ], objSrc, objCopy, n );\r
137         };\r
138         return ret;\r
139 };\r
140 \r
141 /**\r
142  * object が空か?調べます。 object でない場合、undefined が返る\r
143  * @alias X.Object.isEmpty\r
144  * @param {object} v \r
145  * @return {boolean|undefined}\r
146  */\r
147 function X_Object_isEmpty( v ){\r
148         if( !v ) return;\r
149         for( var k in v ){\r
150                 //if( X_EMPTY_OBJECT[ _k ] ) continue;\r
151                 return false;//if( v.hasOwnProperty && v.hasOwnProperty( p ) ) return false; ie4 で動かない、、、\r
152         };\r
153         return true;\r
154 };\r
155 \r
156 /**\r
157  * obj に対し、selector で示した値を返す。メンバを辿れなかった場合、undefined が返る。\r
158  * @alias X.Object.find\r
159  * @param {object} obj\r
160  * @param {string} selector 'navigator>mineTypes>hoge'\r
161  * @return {*}\r
162  */\r
163 function X_Object_find( obj, selector ){\r
164         var selectors = selector.split( '>' );\r
165         \r
166         for( ; selector = selectors.shift(); ){\r
167                 obj = obj[ selector ];\r
168                 if( !obj ) return;\r
169         };\r
170         return obj;\r
171 };\r
172 \r
173 // TODO X.Object.own( obj, name )\r
174 /*\r
175  * Safari の JavaScript の不備 \r
176  * http://nanto.asablo.jp/blog/2006/01/13/209495\r
177  * \r
178  * web.paulownia.jp - JavaScriptとクロージャ\r
179  * https://web.archive.org/web/20070526063400/http://web.paulownia.jp/script/oop/closure.html\r
180  * MacOSX 10.3のsafariにはhasOwnPropertyが実装されていないので、独自に追加する必要があります。\r
181  * \r
182  * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法\r
183  * http://os0x.hatenablog.com/entry/20080901/1220272509\r
184  */\r
185 /*\r
186 Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
187                 var proto = this.constructor && this.constructor.prototype,\r
188                         __p__ = proto && proto.__proto__,\r
189                         v     = this[ p ],\r
190                         r     = false;\r
191                 \r
192                 if( __p__ ) proto.__proto__ = null;\r
193                 \r
194                 if( p in this ){\r
195                         if( v !== v ){\r
196                                 if( proto && ( p in proto ) && proto[ p ] !== proto[ p ] ){ // proto[ p ] is NaN\r
197                                         proto[ p ] = 0; // different value\r
198                                         r = this[ p ] !== this[ p ]; // isNaN?\r
199                                         proto[ p ] = v; // set NaN\r
200                                 } else {\r
201                                         r = true;\r
202                                 };\r
203                         } else\r
204                         if( proto && p in proto && proto[ p ] === v ){\r
205                                 // this と proto に同名で同値が書かれている可能性あり\r
206                                 proto[ p ] = v + ' '; // different value\r
207                                 r = v === this[ p ];\r
208                                 proto[ p ] = v;\r
209                         } else {\r
210                                 r = true;\r
211                         };\r
212                 };\r
213                 \r
214                 if( __p__ ) proto.__proto__ = __p__;\r
215                 \r
216                 return r;\r
217   }); */\r
218 /*\r
219 Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
220                 var proto = this.constructor && this.constructor.prototype,\r
221                         __p__ = proto && proto.__proto__,\r
222                         r     = false,//!!( __p__ && ( proto.__proto__ = null ) )\r
223                         _pro_, v, isNaN;\r
224                 \r
225                 if( __p__ ) proto.__proto__ = null;\r
226                 if( this.__proto__ ){\r
227                         _pro_ = this.__proto__;\r
228                         this.__proto__ = null;\r
229                 };\r
230                 \r
231                 if( p === '__proto__' ){\r
232                         r = !!_pro_;\r
233                 } else {\r
234                         v     = this[ p ];\r
235                         isNaN = v !== v;                \r
236                         \r
237                         if( p in this ){\r
238                                 if( proto && p in proto && ( proto[ p ] === v ) ^ isNaN ){ //true + false, false + true\r
239                                         // this と proto に同名で同値が書かれている可能性あり\r
240                                         proto[ p ] = v + ' '; // different value\r
241                                         r = ( v === this[ p ] ) ^ isNaN; // true + false, false + true\r
242                                         proto[ p ] = v;\r
243                                 } else {\r
244                                         r = true;\r
245                                 };\r
246                         };                      \r
247                 };\r
248 \r
249                 if( __p__ ) proto.__proto__ = __p__;\r
250                 if( _p_ ) this.__proto__ = _pro_;\r
251                 return r;\r
252   }); */\r
253  \r
254  \r
255 \r