超越Jquery_01_isPlainObject分析与重构

yizhihongxing

超越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对象,但是它并没有完美的解决问题:

  1. 不支持对空对象进行判断
  2. 对于DOM节点和window对象也会认为其是普通对象
  3. 还有通过自定义函数生成的对象,如果该函数的原型链上存在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分析与重构 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • Javascript Dom元素获取和添加详解

    关于JavaScript中Dom元素获取和添加,可以分为如下几个方面进行讲解: 一、Dom元素获取 Dom元素是页面上的元素,我们可以通过JavaScript代码获取到Dom元素以便进行操作,下面介绍一些常用的Dom元素获取方式: 1. document.getElementById 这是获取单个元素最常用的方法,通过元素id获取单个Dom元素: var e…

    JavaScript 2023年6月10日
    00
  • JavaScript实现删除,移动和复制文件的方法

    下面就是“JavaScript实现删除、移动和复制文件的方法”的完整攻略。 删除文件 使用 XMLHttpRequest 对象和 AJAX 可以先准备一个简单的页面,其中有一个表单用来选择要删除的文件或文件夹,还有一个删除按钮用来触发删除操作。然后在需要执行删除的那个按钮上添加一个点击事件,将所选中的文件或文件夹通过 AJAX 上传到服务器端进行删除。代码如…

    JavaScript 2023年5月27日
    00
  • 浅谈JavaScript宏任务和微任务执行顺序

    浅谈JavaScript宏任务和微任务执行顺序 在 JavaScript 中,任务被分为 宏任务(macrotask)和 微任务(microtask)。而在 JavaScript 中,事件循环(event loop)来负责管理和执行这些任务。 宏任务(macrotask) 宏任务是 JavaScript 中较为常见的任务类型,包括以下几种: 脚本本身; 用户…

    JavaScript 2023年6月11日
    00
  • javascript格式化日期时间方法汇总

    下面我为大家详细讲解一下“javascript格式化日期时间方法汇总”的完整攻略。 1. 引言 在前端的工作中,日期时间格式转换是一个十分常见的问题。因此,有必要总结一下javascript中处理日期时间的API和格式化日期的方法,以便于在工作中快速有效地使用。 2. Date对象 在javascript中,我们可以使用内置的Date对象来处理日期时间。Da…

    JavaScript 2023年5月27日
    00
  • 性能优化篇之Webpack构建代码质量压缩的建议

    “性能优化篇之Webpack构建代码质量压缩的建议”是对于Webpack构建打包JS的一个性能优化方案。本文将详细讲解如何进行Webpack构建代码质量压缩的过程。 1. 使用Webpack UglifyJsPlugin插件实现代码压缩 在Webpack打包JS之前,参考文档Webpack UglifyJS Plugin,我们可以安装并使用Webpack U…

    JavaScript 2023年5月28日
    00
  • vue elementui 实现搜索栏公共组件封装的实例代码

    下面我将为你讲解”vue elementui 实现搜索栏公共组件封装的实例代码”的完整攻略。 一、需求分析 在实现搜索栏公共组件封装之前,我们需要先确定组件的需求,包括: 搜索栏包含的输入字段类型(文本输入、下拉框选择等); 搜索栏提交查询的方式(点击查询按钮、按下Enter键等); 查询参数的名称和格式; 查询结果的展示方式。 例如我们可以将搜索栏中的输入…

    JavaScript 2023年6月10日
    00
  • js读取cookie方法总结

    JS 读取 Cookie 方法总结 什么是 Cookie? Cookie 是一种存储在用户计算机上的小文件,包含了与某个网站相关的用户信息。浏览器每次向服务器发送请求时,会将 Cookie 信息附加在 HTTP 请求头部中,服务器端可以通过从头部解析得到的 Cookie 信息来判断用户状态并作出相应的响应。 如何读取 Cookie? 以下是几种常用的 JS …

    JavaScript 2023年6月11日
    00
  • 彻底弄懂 JavaScript 执行机制

    彻底弄懂 JavaScript 执行机制 JavaScript 的执行环境 JavaScript 代码的执行必须依赖一个执行环境,该执行环境可以是浏览器、 Node.js 服务器或其它解释器等等,而这些执行环境会为 JavaScript 提供几乎相同的对象和方法,但是在细节上或许会略有不同。 JavaScript 的执行过程 JavaScript 的执行过程…

    JavaScript 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部