isPlainObject
摘抄源码如下:
var class2type = {};
var toString = class2type.toString; //返回表示该对象的字符串
var getProto = Object.getPrototypeOf;//返回指定对象的原型,__proto__的值
var hasOwn = class2type.hasOwnProperty; //返回一个布尔值,属于自身而不是原型为真
var fnToString = hasOwn.toString; //此方法返回当前函数源代码的字符串
var ObjectFunctionString = fnToString.call(Object);
function isPlainObject(obj) {
var proto, Ctor;
if (!obj || toString.call(obj) !== "[object Object]") {
return false;
}
proto = getProto(obj);
if (!proto) {
return true;
}
Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
}
- 首先判断参数是否为Object类型。使用逻辑或||的判断逻辑,在!obj为真(参数是空字符串、数值0、null、NaN、undefined)的情况下直接得到false的结果。然后使用了{}.toString方法(注意不是各个类型自身的toString方法),彻底排除了Boolean、Number、String(以基本包装类型形式)及ES6新增的Symbol四种数据类型及Array、Date、RegExp、Function以及Math、Window这样的单体内置对象等引用类型;
- 然后判断参数是否为字面量创建的对象或者是以Object.prototype 为原型对象创建的对象。首先声明原型对象为null的对象是plainObject,即Object.create(null)。然后保存参数原型proto自身的构造函数(不能是继承来的)至变量Ctor,只有当其构造函数是函数类型(不能被改写成其他类型)且其函数源代码字符串与Object构造函数源代码一致时,为plainObject,也就是说其构造函数就是Object。
网友评论