isPlainObject は、Jquery 1.4 以降に提供された新しいメソッドで、オブジェクトが純粋なオブジェクト (「{}」または「新しいオブジェクト」によって作成されたもの) かどうかを判断するために使用されます。
isPlainObject を使用する
まず、「純粋なオブジェクト」とは何かを理解しましょう。「純粋なオブジェクト」とは、Object から構築されたオブジェクトを指します。では、どのオブジェクトが Object から構築されるのか。最初に負荷を負うのは、 new Object() によって構築されたオブジェクトでなければなりません。 注: Object の後の括弧内には何も追加されません。 Object はすべての「クラス」の基礎であるため、いくつかの特別な動作があります。たとえば、new Object(3) が呼び出されるとき、Number 型のオブジェクトが構築されます。 new Object('') は String 型のオブジェクトを構築します。したがって、{} の形式で定義されたオブジェクトも「純粋なオブジェクト」に属します。 '{}' の本質は new Object() ですが、表現が異なります。さて、コードを見てみましょう:
var objStr = new Object('');
alert(objStr.constructor);//String
alert(isPlainObject(objStr));//false
var objNum = new Object(3) ;
alert (objNum.constructor);//Number
alert(isPlainObject(objNum));//false
function Person(){}
var person = new Person(); >alert(isPlainObject(person));//false
var obj01 = new Object();
obj01.name = 'バカの座右の銘';
alert(isPlainObject(obj01));//true
alert( isPlainObject({name:'Motto of Idiot'}));//true
isPlainObject ソース コード分析
次のコードは、Jquery の isPlainObject の完全版です。コメントは非常に詳細です。これ以上言うことはありません。
var toString = Object.prototype.toString,
hasOwnProperty = Object.prototype.hasOwnProperty;
function isPlainObject( obj ) {
// オブジェクトである必要があります。
// IE のため、コンストラクター プロパティの存在も確認する必要があります。 .
//DOM ノードとウィンドウ オブジェクトも通過しないようにします。
//windows オブジェクト:toString.call(window):IE [オブジェクト オブジェクト] FF [オブジェクト ウィンドウ] chrome [ウィンドウ] global] safari [object DOMWindow]
//DOM ノード:toString.call(#div01):IE [object Object] FF [object Window] chrome [object global] safari [object DOMWindow]
//結論: obj.nodeType || obj.setInterval は主に IE ブラウザを判断するために使用されます
//注: 履歴、位置、ナビゲーター、画面の setInterval は未定義です
if ( !obj || toString.call(obj) ! == "[object Object]" || obj.nodeType || obj.setInterval ) {
return false;
}
// 独自のコンストラクター プロパティはオブジェクトでなければなりません
// カスタム オブジェクトを削除します関数 Person(){} などの組み込みオブジェクトの判定 var p = new Person();String,Number
if ( obj.constructor //コンストラクタプロパティがある
&& !hasOwnProperty.call( obj, "constructor" ) //また、コンストラクター プロパティはプロトタイプ チェーンで定義する必要があります
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")//プロトタイプには isPrototypeOf メソッドがあります。通常、オブジェクトのプロトタイプ内でのみこのメソッドのみ
) {
return false
}
// 独自のプロパティが最初に列挙されるため、高速化するために、
// 最後のプロパティが
//複雑なクラス構造の場合、継承がある場合...
/*
//単純なテスト
function Animal(name){
}
関数 人(名前,年齢){
Animal.call(この,名前);
この.年齢 = 年齢;
}
var p = 新しい人('jxl', 20);
for(key in p){
alert(hasOwnProperty.call( p, key ))//true , false
}
*/
var key; for ( key in obj ) {}
return key === unknown || hasOwnProperty.call( obj, key );
}
質問する
個人的にはこの実装はより複雑で、バグがあると感じます。
単純なバグ、履歴、位置、ナビゲーター、画面は、isPlainObject の検出を通じて連続して true を返すことができます。
私の解決策を見てみましょう (バグを修正し、単純化します):
if(obj&&Object.prototype. toString.call(obj)= ==="[object オブジェクト]"&&obj.constructor===Object &&!hasOwnProperty.call(obj, "constructor")){
var key; obj ) {}
return key === unknown || hasOwnProperty.call( obj, key );
return
}
もありますバグ、そしてそれは解決不可能なバグです:
コードをコピー