IsPlainObject is a new method provided after Jquery1.4 to determine whether the object is a pure object (created through {} Or newObject ). IsPlainObject is a new method provided after Jquery1.4 to determine whether the Object is a pure Object (created through "{}" or "new Object ).
Use isPlainObject
First, let's take a look at what is 'pure object'. A simple understanding of 'pure object' refers to the Object constructed by the Object. Which objects are constructed by objects. First, it must be constructed by the new Object (). Note: nothing can be added to the brackets behind the Object. Because Object is the foundation of all 'class', it has some special behaviors. For example, when new Object (3) is called, a Number Object is constructed. New Object ('') constructs a String-type Object. Then the objects defined in the form of {} also belong to 'pure object '. The essence of '{}' is new Object (), but the form is different. Okay. Let's take a look at the Code:
The Code is as follows:
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 = 'dummies ';
Alert (isPlainObject (obj01); // true
Alert (isPlainObject ({name: 'dummies '}); // true
IsPlainObject source code analysis
The following code is the complete version of isPlainObject in Jquery. The comments are very detailed and I will not talk about them much.
The Code is as follows:
Var toString = Object. prototype. toString,
HasOwnProperty = Object. prototype. hasOwnProperty;
Function isPlainObject (obj ){
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
// Make sure that DOM nodes and window objects don't pass through, as well
// Windows objects: toString. call (window): IE [object Object] FF [object Window] chrome [window global] safari [object DOMWindow]
// DOM nodes: toString. call (# p01): IE [object Object] FF [object Window] chrome [object global] safari [object DOMWindow]
// Conclusion: obj. nodeType | obj. setInterval is mainly used for judging by IE browser.
// Note: The setInterval of history, location, navigator, and screen is undefined.
If (! Obj | toString. call (obj )! = "[Object Object]" | obj. nodeType | obj. setInterval ){
Return false;
}
// Not own constructor property must be Object
// Except the judgment of custom objects and built-in objects, such as function Person () {} var p = new Person (); String, Number
If (obj. constructor // has the constructor attribute
&&! HasOwnProperty. call (obj, "constructor") // and the constructor attribute must be defined in the prototype chain.
&&! HasOwnProperty. call (obj. constructor. prototype, "isPrototypeOf") // The prototype contains the isPrototypeOf method. This method is only available in the Object prototype.
){
Return false;
}
// Own properties are enumerated firstly, so to speed up,
// If last one is own, then all properties are own.
// For complex class structures, such as inheritance...
/*
// A simple test
Function Animal (name ){
}
Function Person (name, age ){
Animal. call (this, name );
This. age = age;
}
Var p = new Person ('jxl ', 20 );
For (key in p ){
Alert (hasOwnProperty. call (p, key) // true, false
}
*/
Var key;
For (key in obj ){}
Return key = undefined | hasOwnProperty. call (obj, key );
}
Raise Questions
I personally feel that this implementation is complicated and has bugs.
Simple bugs, history, location, navigator, and screen can be detected by isPlainObject sequentially to return true.
Let's take a look at one of my solutions (modifying bugs and simplifying them ):
The Code is as follows:
Function isPlainObject (obj ){
If (obj & Object. prototype. toString. call (obj) === "[object Object]" & obj. constructor === Object &&! HasOwnProperty. call (obj, "constructor ")){
Var key;
For (key in obj ){}
Return key = undefined | hasOwnProperty. call (obj, key );
}
Return false;
}
There is also a BUG, and it is an unsolved BUG:
The Code is as follows:
Function m (){};
M. prototype. constructor = Object; // Yes
Obj = new m;
Alert (isPlainObject (obj); // true
Let's look at the same thing:
The Code is as follows:
Function m (){};
M. prototype = {};
Obj = new m;
Alert (isPlainObject (obj); // true
There is no answer!
No solution
I thought this problem was a good solution. After in-depth analysis, I found that it was an unsolved problem. The reason is as follows:
The Code is as follows:
Function Person (){};
Person. prototype. constructor = Object;
Var person = new Person;
Let's take a look at the current state of person:
The only connection between person and its constructor is the constructor attribute in its prototype chain. In our judgment, whether it is a 'pure object' is mainly based on the constructor of the object instance. If we point it to the Object, as we see in the middle, then the person and Person have no relationship in the code. This makes the type judgment problematic.