首先我们需要一个判断类型的神码。
var toString = [].toString,
hasOwn = Object.prototype.hasOwnProperty;
var types = {
'[object Boolean]':'bool',
'[object Number]' : 'number',
'[object String]' : 'string',
'[object Object]':'object',
'[object Array]':'array',
'[object Function]':'function',
'[object Date]' : 'date',
'[object RegExp]' : 'regExp',
};
var type = function(obj){
return obj === null ? String(obj) : types[toString.call(obj)] || 'object';
};
var isWindow = function(obj){
return obj && typeof obj === 'object' && 'setInterval' in obj;
};
var isArray = Array.isArray || function(obj){
return type(obj) === 'array';
};
神在哪里,神在他让js有了确定的类型。。。
什么是纯粹的object?
我也不好说。
什么不纯粹呢?
通过构造函数new的对象不纯粹。
Object.create(null)不纯粹。
if(obj.constructor && !hasOwn.call(obj, 'constructor')
&& !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf')){
return false;
}
如果是Object.create(null)构造的对象,是没有constructor指针的
这也是(obj.construcor &&)的判断结果。
其次用构造函数new的对象,constructor存在于obj原型链中,而isPrototypeOf在constructor的原型链上,而不在constructor原型上!
var isPlainObject = function(obj){
if(!obj || type(obj) !== 'object' || isWindow(obj) || obj.nodeType){
return false;
}
try{
if(obj.constructor && !hasOwn.call(obj, 'constructor')
&& !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf')){
return false;
}
}catch(e){
return false
}
var key;
for(key in obj){}
return key === undefined || hasOwn.call(obj, key)
}
try-catch主要是为了兼容IE