所有工具函数
还是老样子,先看看axios
的工具函数有哪些,先心里有个印象,然后再逐个分析。
直接拉到最下面,可以看到axios
的工具函数都是统一导出的:
export default {isArray, // 判断是否是数组isArrayBuffer, // 判断是否是 ArrayBufferisBuffer, // 判断是否是 BufferisFormData, // 判断是否是 FormDataisArrayBufferView, // 判断是否是 ArrayBufferViewisString, // 判断是否是字符串isNumber, // 判断是否是数字isBoolean, // 判断是否是布尔值isObject, // 判断是否是对象isPlainObject, // 判断是否是纯对象isUndefined, // 判断是否是 undefinedisDate, // 判断是否是日期isFile, // 判断是否是文件isBlob, // 判断是否是 BlobisRegExp, // 判断是否是正则isFunction, // 判断是否是函数isStream, // 判断是否是 StreamisURLSearchParams, // 判断是否是 URLSearchParamsisTypedArray, // 判断是否是 TypedArrayisFileList, // 判断是否是 FileListforEach, // 遍历对象merge, // 合并对象extend, // 扩展对象trim, // 去除字符串两边的空格stripBOM, // 去除字符串的 BOMinherits, // 继承toFlatObject, // 将对象转换为扁平对象kindOf, // 获取对象的类型kindOfTest, // 判断对象的类型endsWith,// 判断字符串是否以指定的字符串结尾toArray, // 将类数组转换为数组forEachEntry, // 遍历对象的键值对matchAll, // 匹配所有的字符串isHTMLForm, // 判断是否是 HTMLFormhasOwnProperty, // 判断对象是否有指定的属性hasOwnProp: hasOwnProperty,// 判断对象是否有指定的属性reduceDescriptors, // 降低描述符freezeMethods, // 冻结方法toObjectSet, // 将数组或者字符串转换为类似`Set`的对象toCamelCase, // 将字符串转换为驼峰命名noop, // 空函数toFiniteNumber, // 将字符串转换为有限数字findKey, // 查找对象的键global: _global, // 全局对象isContextDefined, // 判断上下文是否定义toJSONObject // 将字符串转换为 JSON 对象
};
isArray
:判断是否是数组isArrayBuffer
:判断是否是 ArrayBufferisBuffer
:判断是否是 BufferisFormData
:判断是否是 FormDataisArrayBufferView
:判断是否是 ArrayBufferViewisString
:判断是否是字符串isNumber
:判断是否是数字isBoolean
:判断是否是布尔值isObject
:判断是否是对象isPlainObject
:判断是否是纯对象isUndefined
:判断是否是 undefinedisDate
:判断是否是日期isFile
:判断是否是文件isBlob
:判断是否是 BlobisRegExp
:判断是否是正则isFunction
:判断是否是函数isStream
:判断是否是 StreamisURLSearchParams
:判断是否是 URLSearchParamsisTypedArray
:判断是否是 TypedArrayisFileList
:判断是否是 FileListforEach
:遍历对象merge
:合并对象extend
:扩展对象trim
:去除字符串两边的空格stripBOM
:去除字符串的 BOMinherits
:继承toFlatObject
:将对象转换为扁平对象kindOf
:获取对象的类型kindOfTest
:判断对象的类型endsWith
,// 判断字符串是否以指定的字符串结尾toArray
:将类数组转换为数组forEachEntry
:遍历对象的键值对matchAll
:匹配所有的字符串isHTMLForm
:判断是否是 HTMLFormhasOwnProperty
:判断对象是否有指定的属性hasOwnProp
: hasOwnProperty, :判断对象是否有指定的属性reduceDescriptors
:降低描述符freezeMethods
:冻结方法toObjectSet
:将数组或者字符串转换为类似Set
的对象toCamelCase
:将字符串转换为驼峰命名noop
:空函数toFiniteNumber
:将字符串转换为有限数字findKey
:查找对象的键global: _global
:全局对象isContextDefined
:判断上下文是否定义toJSONObject
:将字符串转换为 JSON 对象
一共有46
个工具函数,比Vue2
的工具函数多了很多,同时也发现有很多同名的工具函数,例如:
1.isArray
2.isRegExp
3.isFunction
4.isObject
5.isPlainObject
6.extend
7.noop
别看这么多,其中对于类型判断的函数只有少数几个需要关注,其他的都是使用同样的方式来实现的,如下:
isArrayBuffer
isBuffer
isString
isNumber
isUndefined
isDate
isFile
isBlob
isRegExp
isFunction
isStream
isURLSearchParams
isFileList
isHTMLForm
一共14
个,这些函数都是通过kindOf
来实现的,上面这些相同的会在源码阅读中移除。
正式阅读
这里的kindOf
和kindOfTest
优先阅读,因为这两个函数是用来判断类型的,上面移除的14
个函数都是通过这两个函数来实现的,所以这两个函数非常重要也非常经典。
kindOf
// utils is a library of generic helper functions non-specific to axios
const {toString} = Object.prototype;
const kindOf = (cache => thing => {const str = toString.call(thing);return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
})(Object.create(null));
kindOf
函数用于获取对象的类型,比如kindOf({})
返回的是object
;
它是一个立即执行函数,返回一个函数,这个函数接收一个参数,这个参数就是要获取类型的对象;
抛开立即执行函数不说,kindOf
函数的核心代码只有两行:
const {toString} = Object.prototype;
const kindOf = (thing) => {const str = toString.call(thing);return str.slice(8, -1).toLowerCase();
};
这里的处理其实和Vue2
中类型判断的处理是一样的,都是通过Object.prototype.toString
来获取对象的类型;
kindOf
函数的返回值是一个字符串,这个字符串就是对象的类型,不过这里使用了一个缓存,这样就不用每次都去执行str.slice(8, -1).toLowerCase()
了;
kindOfTest
const kindOfTest = (type) => {type = type.toLowerCase();return (thing) => kindOf(thing) === type
}
kindOfTest
函数用于判断对象的类型,同样也是一个高阶函数;
它接收一个参数,这个参数就是要判断的类型,返回一个函数,这个函数接收一个参数,这个参数就是要判断的对象;
返回的函数通过函数柯里化的特性,将type
参数固定下来,这样就可以通过kindOfTest('object')
来判断对象的类型了;
也就是axios
中的大多数类型判断都是通过kindOfTest
函数来实现的;
isArrayBuffer
const {toString} = Object.prototype;
const kindOf = (cache => thing => {const str = toString.call(thing);return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());
})(Object.create(null));
const kindOfTest = (type) => {type = type.toLowerCase();return (thing) => kindOf(thing) === type
}
/**
* Determine if a value is an ArrayBuffer
*
* @param {*} val The value to test
*
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
*/
const isArrayBuffer = kindOfTest('ArrayBuffer');
这个就是使用kindOfTest
函数来判断对象的类型,isArrayBuffer
函数接收一个参数,这个参数就是要判断的对象,返回一个布尔值,表示这个对象是否是ArrayBuffer
类型;
上面过滤掉的14
个函数都是通过这种方式来实现的,这里就不一一列举了;
这是一个非常经典的高阶函数应用模式,函数柯里化的应用,可以看看:✨从柯里化讲起,一网打尽 JavaScript 重要的高阶函数
isArray
/**
* Determine if a value is an Array
*
* @param {Object} val The value to test
*
* @returns {boolean} True if value is an Array, otherwise false
*/
const {isArray} = Array;
直接使用解构赋值,将Array.isArray
赋值给isArray
,和Vue2
的实现方式一样;
isBuffer
/**
* Determine if a value is undefined
*
* @param {*} val The value to test
*
* @returns {boolean} True if the value is undefined, otherwise false
*/
const isUndefined = typeOfTest('undefined');
/**
* Determine if a value is a Function
*
* @param {*} val The value to test
* @returns {boolean} True if value is a Function, otherwise false
*/
const isFunction = typeOfTest('function');
/**
* Determine if a value is a Buffer
*
* @param {*}