2 * name in object 構文が使えない環境で構文解析エラーを回避するためにこのメソッドを使用します。
\r
3 * 但し for( name in object ) については構文解析エラーになる環境はありません。
\r
4 * @alias X.Object.inObject
\r
6 * @param {string|number} name
\r
7 * @param {object} obj
\r
8 * @return {boolean} name が定義されている(値が undefined や null でも) -> true
\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
15 if( _ === name ) return true;
\r
19 new Function( 'a,b', 'return (""+a) in b' );
\r
22 // ------------------------------------------------------------------------- //
\r
23 // --- interface ----------------------------------------------------------- //
\r
24 // ------------------------------------------------------------------------- //
\r
27 * Object に関する関数を集めたものです。
\r
28 * @namespace X.Object
\r
33 'copy' : X_Object_copy,
\r
35 'deepCopy' : X_Object_deepCopy,
\r
37 'override' : X_Object_override,
\r
39 'clear' : X_Object_clear,
\r
41 'isEmpty' : X_Object_isEmpty,
\r
43 'inObject' : X_Object_inObject,
\r
45 'find' : X_Object_find
\r
46 // TODO hasOwnProperty
\r
49 // ------------------------------------------------------------------------- //
\r
50 // --- implements ---------------------------------------------------------- //
\r
51 // ------------------------------------------------------------------------- //
\r
53 * 単純なクローンでメンバーをコピーしたオブジェクトを返します。 k in null でエラーになる Opera7- に対策済。
\r
54 * @alias X.Object.copy
\r
55 * @param {object|Array} src コピー元のオブジェクトです。
\r
56 * @return {object|Array}
\r
58 function X_Object_copy( src ){
\r
61 if( !src || !X_Type_isObject( src ) ) return src;
\r
65 //if( X_EMPTY_OBJECT[ k ] ) continue;
\r
66 ret[ k ] = src[ k ];
\r
72 * オブジェクトにオブジェトのメンバーをコピーします。同じ名前のメンバーは上書きされます。
\r
73 * @alias X.Object.override
\r
74 * @param {object} target コピーされるオブジェクトです。返り値はこのオブジェクトです。
\r
75 * @param {object} src コピー元のオブジェクトです。
\r
76 * @return {object} target が返る。
\r
78 function X_Object_override( target, src ){
\r
80 if( !src || !X_Type_isObject( src ) ) return target;
\r
82 //if( X_EMPTY_OBJECT[ k ] ) continue;
\r
83 target[ k ] = src[ k ];
\r
89 * オブジェクトの全てのメンバーを破棄します。
\r
90 * @alias X.Object.clear
\r
91 * @param {object} obj。
\r
93 function X_Object_clear( obj, k ){
\r
103 * オブジェクト(object, Array)のメンバーを探索して、ディープコピーしたオブジェクトを返します。
\r
104 * オブジェクトが循環参照している場合は、既にコピーしているオブジェクトが現れた時点で、先に作成しているコピーの参照を返すので無限にループすることはありません。
\r
105 * @alias X.Object.deepCopy
\r
106 * @param {object|Array} src コピー元のオブジェクトです。
\r
107 * @return {object|Array}
\r
109 function X_Object_deepCopy( src ){
\r
110 return X_Object_deepCopy_( src, [], [], -1 );
\r
113 function X_Object_deepCopy_( src, objSrc, objCopy, n ){
\r
116 if( !src ){ // 0, "", null, undefined, NaN, false
\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
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
131 // string, number, true
\r
135 //if( X_EMPTY_OBJECT[ k ] ) continue;
\r
136 ret[ k ] = X_Object_deepCopy_( src[ k ], objSrc, objCopy, n );
\r
142 * object が空か?調べます。 object でない場合、undefined が返る
\r
143 * @alias X.Object.isEmpty
\r
144 * @param {object} v
\r
145 * @return {boolean|undefined}
\r
147 function X_Object_isEmpty( v ){
\r
150 //if( X_EMPTY_OBJECT[ _k ] ) continue;
\r
151 return false;//if( v.hasOwnProperty && v.hasOwnProperty( p ) ) return false; ie4 で動かない、、、
\r
157 * obj に対し、selector で示した値を返す。メンバを辿れなかった場合、undefined が返る。
\r
158 * @alias X.Object.find
\r
159 * @param {object} obj
\r
160 * @param {string} selector
\r
163 function X_Object_find( obj, selector ){
\r
164 var selectors = selector.split( '>' );
\r
166 for( ; selector = selectors.shift(); ){
\r
167 obj = obj[ selector ];
\r
173 // TODO X.Object.own( obj, name )
\r
175 * Safari の JavaScript の不備
\r
176 * http://nanto.asablo.jp/blog/2006/01/13/209495
\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
182 * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法
\r
183 * http://os0x.hatenablog.com/entry/20080901/1220272509
\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
192 if( __p__ ) proto.__proto__ = null;
\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
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
214 if( __p__ ) proto.__proto__ = __p__;
\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
225 if( __p__ ) proto.__proto__ = null;
\r
226 if( this.__proto__ ){
\r
227 _pro_ = this.__proto__;
\r
228 this.__proto__ = null;
\r
231 if( p === '__proto__' ){
\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
249 if( __p__ ) proto.__proto__ = __p__;
\r
250 if( _p_ ) this.__proto__ = _pro_;
\r