我发现了axios源码工具函数中的一个小bug

简介: 最开始我一看很蒙蔽,很多时候自己并不会去写这样的函数,说白了还是自己代码底子不行。可能很多大佬一看就明白了,所以基础很重要,基础很重要,基础很重要。箭头函数算是ES6中新增的。

image.png


大家好,我是 那个曾经的少年回来了。10年前我也曾经年轻过,如今已步入被淘汰的年龄,但如下幡然醒悟,所以活在当下,每天努力一点点,来看看2024年的时候自己会是什么样子吧,2024年的前端又会是什么样子,而2024年的中国乃至全球又会变成什么样子,如果你也有想法,那还不赶紧行动起来。期待是美好的,但是更重要的是要为美好而为之奋斗付诸于行动。


最近在读axios的源码,有一些晦涩难懂,于是乎就先来入手一下 axiosutils 工具函数, 于是有趣的事情发生了。接下来就跟随我的思路来看看我发现的小问题吧,如果是大佬,就此别过。


1、两个箭头函数的演绎


const typeOfTest = type => thing => typeof thing === type;


最开始我一看很蒙蔽,很多时候自己并不会去写这样的函数,说白了还是自己代码底子不行。可能很多大佬一看就明白了,所以基础很重要,基础很重要,基础很重要。箭头函数算是ES6中新增的。


那我先来一个最简单的箭头函数


const f = v => v;
// 等同于
const f = function (v) {
  return v;
};


相信有点JavaScript基础的朋友们应该都能看懂上面的代码,所以参考上面的小例子,来类比一下


const typeOfTest = function(type) {
  // 也就是把第一个箭头函数后面全部返回即可
  return thing => typeof thing === type;
}


这个样子我相信很多人都能看明白了,不过此时我们还可以再次拆解,将两个箭头函数都用ES5的写法改写


let typeOfTest = function(type) {
  return function(thing) {
    return typeof thing === type;
  }
}


再次看上面的代码,就再清楚不过了,其实发现调用typeOfTest会返回一个函数,那么就说明调用完之后还需要调用执行,而且再次调用还需要传入一个参数


typeOfTest('undefined')(undefined)


2、函数本身的意义


这里其实就是第一次调用先传入一个已知的数据类型,第二次调用再传入参数值,通过 typeof 解析出类型与第一次传入类型进行判断,返回 true 或者 false


所以就有了axios源码 utils.js文件中一系列的函数


// 判断是否为undefined的方法
const isUndefined = typeOfTest('undefined');
// 判断是否为字符串的方法
const isString = typeOfTest('string');
// 判断是否为函数的方法
const isFunction = typeOfTest('function');
// 判断是否为Boolean类型的方法
const isBoolean = thing => thing === true || thing === false;
// 我觉得可以添加一个
const isBoolean = typeOfTest('boolean');
// 判断是否为数值类型的方法
const isNumber = typeOfTest('number');


这里我故意将 isNumber放到最后。


这里其实就是我发现axios中一个小bug。


3、判断是否是number的问题


typeof NaN 的时候,其实返回的也是 number


NaN ,可以翻译为 not a number ,即不是一个数字。 NaN 是一个“警戒值”(sentinel value,有特殊用途的常规值),常用来指出数字类型中的错误情况,即:“执行数学运算没有成功,这是返回的结果” 所以有时候我们判断的时候可能要通过 Number.isNaN,而 Number.isNaN 是 ES6 中新增的函数,Number.isNaN()只有对于 NaN 才返回 true,非 NaN 一律返回 false。


所以上面判断是否为number数值的方法做一个小的调整,先判断一下是否为NaN


const isNumber = (thing) => Number.isNaN(thing)? false: typeOfTest('number')(thing)


这里还要关注一下 IsNaN 方法,和 Number.isNaN 的区juejin.cn/post/684490…


isNaN(NaN); // true 
isNaN('A String'); // true 
isNaN(undefined); // true 
isNaN({}); // true 
Number.isNaN('A String'); // false 
Number.isNaN(undefined); // false 
Number.isNaN({}); // false
Number.isNaN(NaN); // true 


我想只有Number.isNaN(NaN) 是我们想要的结果,所以简单的来说 isNaN 方法算是之前JavaScript遗留的 bug 吧,然后 ES6 新增了 Number.isNaN,这个问题从而得到了解决。


4、哪些情况会导致NaN值的产生呢


Number(NaN)       // NaN
Number(undefined) // NaN
Number('abc')     // NaN
Number('null')    // 0
Number('2.45s')   // NaN
parseFloat(NaN)       // NaN
parseFloat(undefined) // NaN
parseFloat(null)      // NaN
parseFloat('abc')     // NaN
parseFloat('2.45s')   // 2.45
parseInt(NaN)       // NaN
parseInt(undefined) // NaN
parseInt(null)      // NaN
parseInt('abc')     // NaN
parseInt('2.45s')   // 2
1+NaN       // NaN
1+undefined // NaN
1+null      // 1


其实上面要注意一下 Number(null) 的值为0,并且 1+null的值为 1。


parseIntparseFloat是将字符串转换为数值,从第一个字符(位置0)开始解析每个字符。而且也是一直解析到末尾,或者解析到遇见一个无效数字或者无效的浮点数字字符为止。


Number可以将任意类型的字符转换为数值类型,根据具体类型进行输出判断,主要的几种判断方式我在上面已经列出。


5、判断是否是对象的方法


但是我发现判断是否是一个对象,这个判断axios倒是特意做了一个判断


const isObject = (thing) => thing !== null && typeof thing === 'object';


typeof null 输出 object:null 作为一个基本数据类型为什么会被 typeof 运算符识别为 object 类型呢?这个 bug 是第一版 Javascript 留下来的,javascript 中不同对象在底层都表示为二进制,而 javascript 中会把二进制前三位都为 0 的判断为 object 类型,而 null 的二进制表示全都是 0,自然前三位也是 0,所以执行 typeof 时会返回 'object'。 ----引用自《你不知道的 javascript(上卷)》


6、总结


  • typeof 作为类型判断的两个缺陷


  • 判断是否为number类型,要将NaN考虑进去
  • 判断是否为object类型,要将null考虑进行


  • 箭头函数嵌套的解析,将复杂问题简单化


  • 如果不使用typeof判断类型,可以考虑使用 Object.prototype.toString 这也是 axios中使用的一种方式。


  • 了解 typeof NaN 输出number的问题


  • 了解 typeof null 输出object的问题


我的个人博客:vue.tuokecat.com/blog

我的个人github:github.com/aehyok

我的前端项目:pnpm + monorepo + qiankun + vue3 + vite3 + 工具库、组件库 + 工程化 + 自动化

不断完善中,整体框架都有了

在线预览:vue.tuokecat.com

github源码:github.com/aehyok/vue-…

目录
相关文章
|
6天前
|
前端开发 API
Axios请求成功和失败时分别执行哪个函数?
Axios请求成功和失败时分别执行哪个函数?
26 1
|
6天前
|
JSON JavaScript 前端开发
基于 JavaScript 的网络请求工具库 axios 的使用介绍
基于 JavaScript 的网络请求工具库 axios 的使用介绍
74 3
|
6天前
|
前端开发
Axios请求成功和失败时分别执行哪个函数?
Axios请求成功和失败时分别执行哪个函数?
|
6天前
|
前端开发
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
AJAX发送请求方法封装和请求函数底层刨析以及axios二次封装
|
6天前
|
存储 JSON 缓存
【源码共读】axios的46个工具函数
【源码共读】axios的46个工具函数
110 0
|
6天前
|
资源调度 前端开发 JavaScript
Axios大揭秘:咱们怎么玩转这个牛X的HTTP工具
Axios大揭秘:咱们怎么玩转这个牛X的HTTP工具
37 0
|
9月前
|
前端开发 JavaScript UED
Axios网络请求:前端数据交互的强大工具
本篇深入介绍了Axios网络请求库的使用,涵盖了基本的GET和POST请求、拦截器的应用、并发请求的处理以及取消请求的方法。通过详细的代码示例,读者可以了解如何在前端应用中使用Axios进行数据交互,实现高效、可靠的网络请求,从而提升应用性能和用户体验。无论是单一请求还是多个请求的并发处理,Axios都展现了强大的功能,为前端开发者提供了一种优秀的解决方案。
183 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第六十一天-axios源码总结2
前端学习笔记202307学习笔记第六十一天-axios源码总结2
39 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第六十一天-axios源码总结1
前端学习笔记202307学习笔记第六十一天-axios源码总结1
33 0
|
9月前
|
前端开发
前端学习笔记202307学习笔记第六十一天-axios源码总结2
前端学习笔记202307学习笔记第六十一天-axios源码总结2
28 0