Home >Web Front-end >JS Tutorial >Beyond Jquery_01_isPlainObject analysis and reconstruction_javascript skills

Beyond Jquery_01_isPlainObject analysis and reconstruction_javascript skills

WBOY
WBOYOriginal
2016-05-16 18:18:22958browse

isPlainObject is a new method provided after Jquery 1.4, used to determine whether the object is a pure object (created through "{}" or "new Object").

Use isPlainObject
First, let’s understand what a ‘pure object’ is. A simple understanding of ‘pure object’ refers to an object constructed from Object. So which objects are constructed from Object. The first thing to bear the burden must be the object constructed by new Object(). Note: nothing is added in the brackets after Object. Because Object is the foundation of all 'classes', it has some special behaviors. For example, when new Object(3) is called, a Number type object will be constructed. new Object('') will construct an object of type String. Then objects defined in the form {} also belong to 'pure objects'. The essence of '{}' is new Object(), but its expression is different. Okay, let’s look at a piece of code:

Copy 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 = 'Idiot's motto';
alert(isPlainObject(obj01));//true
alert( isPlainObject({name:'Motto of Idiot'}));//true

isPlainObject source code analysis
The following code is the complete version of isPlainObject in Jquery. The comments are very detailed. I Not much more to say.
Copy code 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(#div01):IE [object Object] FF [object Window] chrome [object global] safari [object DOMWindow]
//Conclusion: obj.nodeType || obj.setInterval is mainly used to judge IE browsers
//Note: 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
// Remove custom objects and Judgment of built-in objects, such as function Person(){} var p = new Person();String,Number
if ( obj.constructor //There is constructor property
&& !hasOwnProperty.call(obj, "constructor" ) //And the constructor property must be defined in the prototype chain
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")//And there is an isPrototypeOf method in the prototype, generally only in the prototype of Object Only this method
) {
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, if there is 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 );
}

Ask a question
Personally, I feel that this implementation is more complicated, and there are BUG.
Simple BUG, ​​history, location, navigator, screen can sequentially return true through the detection of isPlainObject.
Let’s take a look at my solution (modify BUG, ​​simplify):
Copy code 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 unsolvable BUG :
Copy code The code is as follows:

function m(){};
m.prototype.constructor=Object; //Must kill
obj=new m;
alert(isPlainObject(obj)); //true

Another one with the same logic:
Copy the code The code is as follows:

function m(){};
m.prototype = {};
obj=new m;
alert(isPlainObject(obj)); //true

This answer is unsolvable!

The answer is unsolvable
I thought this problem was easy to solve, but after digging deeper, I found that it was an unsolvable problem. The reason is as follows:
Copy code 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:
Beyond Jquery_01_isPlainObject analysis and reconstruction_javascript skills
person and its construction The only connection to the function Person is the constructor attribute in its prototype chain. When we judge whether it is a 'pure object', it is mainly based on the constructor of the object instance. If we point it to Object, as you can see in the picture, then person and Person have no relationship in code. It is precisely because of this that problems arise in type judgment.
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn