isPlainObject函数用于判断传入的对象是否为纯粹的JavaScript对象。具体实现如下:
超越Jquery_01_isPlainObject分析与重构
1. isPlainObject函数分析
isPlainObject函数用于判断传入的对象是否为纯粹的JavaScript对象。具体实现如下:
function isPlainObject(obj) {
var proto, Ctor;
// 剔除null和非对象类型
if (!obj || {}.toString.call(obj) !== "[object Object]") {
return false;
}
proto = Object.getPrototypeOf(obj);
// 没有原型的对象为纯粹的JavaScript对象
if (!proto) {
return true;
}
// 构造函数的原型为Object的实例
Ctor = {}.hasOwnProperty.call(proto, "constructor") && proto.constructor;
return typeof Ctor === "function" && {}.toString.call(Ctor) === {}.toString.call(Object);
}
- 首先判断传参是否为null或者非对象类型,如果是则返回false;
- 然后获取对象的原型对象。
- 没有原型对象的是普通对象(遵循ECMAScript规范),将其视为纯粹对象;
- 通过对象原型判断对象是否通过自定义构造函数生成,如果是则从构造函数原型上查询是否存在Object构造函数,此时这个对象就被视为纯粹JS对象返回true。
2. isPlainObject函数存在的问题
虽然isPlainObject函数能够比较准确地判断传入的对象是否为纯粹JavaScript对象,但是它并没有完美的解决问题:
- 不支持对空对象进行判断
- 对于DOM节点和window对象也会认为其是普通对象
- 还有通过自定义函数生成的对象,如果该函数的原型链上存在Object构造函数,也会被识别为纯粹JavaScript对象,但并非如此。
3. isPlainObject函数重构
下面的代码能够对isPlainObject函数进行完美的重构:
function isPlainObject(obj) {
// 判断是否为对象类型
if (!obj || typeof obj !== 'object' || obj.nodeType || obj.window === obj) {
return false;
}
// 是否拥有Object原型链上的isPrototypeOf属性
if (obj.constructor && !Object.prototype.hasOwnProperty.call(obj.constructor.prototype, 'isPrototypeOf')) {
return false;
}
return true;
}
- 首先,判断是否为非null的对象类型或者非window的全局对象;
- 如果是DOM节点或全局window对象,则返回false;
- 如果是自定义构造函数生成的对象,则无法通过Object.prototype去验证其是否具有isPrototypeOf属性,也返回false;
- 如果存在isPrototypeOf属性,则一定为纯粹对象。
4. 示例说明
例如,在以下的情况下,isPlainObject函数就会存在不准确的情况:
// 定义一个自定义构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 调用自定义构造函数创建对象
var person1 = new Person('张三', 18);
var isPureObject1 = $.isPlainObject(person1); // 这里将被识别为纯粹对象,因为Person的原型链上存在Object构造函数
// 如下的情况则不会被题识别为纯粹对象,因为obj定义即为空对象
var obj = {};
var isPureObject2 = $.isPlainObject(obj); // 这里也会被误认为不是纯粹对象。
最终,通过isPlainObject函数重构,能够避免以上两种情况的误判。
沃梦达教程
本文标题为:超越Jquery_01_isPlainObject分析与重构
基础教程推荐
猜你喜欢
- HTML clearfix清除浮动讲解 2022-11-20
- CSS中px em rem区别与使用 2023-12-21
- ajax快速解决参数过长无法提交成功的问题 2023-01-26
- 如何学习html的各种标签 2022-11-13
- Ajax工作原理及优缺点实例解析 2023-02-23
- 使用Vite从零搭建前端项目的详细过程 2022-10-22
- vue一些常用的语法 2023-10-08
- Unicode中的CJK(中日韩统一表意文字)字符小结 2022-09-21
- 基于fileUpload文件上传带进度条效果的实例(必看) 2023-02-14
- Ajax动态为下拉列表添加数据的实现方法 2023-01-26