一文带你掌握axios 工具函数
一条会coding的Shark 人气:0前言
在上周看做项目的时候看到了项目里封装的 axios
,对其封装的原理没有弄清楚,于是周末的时候便抽了点空闲时间来看了看 axios
的源码,将其研究研究。
源码阅读
这里就不单独介绍 axios
了,对于 axios
想必大家都有过了解。咱们直接进入源码阅读的主题。我们今天主要看的是源码中的utils.js文件,里面包含了很多工具函数。
这是截取的其中一部分,粗略看下来大概有四五十个工具函数,接下来开始分享其中一些这里面我平时不怎么见到过或者用到过的工具函数,来学习一下。
kindOf
const {toString} = Object.prototype; const {getPrototypeOf} = Object; const kindOf = (cache => thing => { const str = toString.call(thing); return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); })(Object.create(null));
kindOf
主要作用是获取对象的类型。有点类似于 typeof
,typeof
是判断对象的类型的作用。
isBuffer
function isBuffer(val) { return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val); }
Buffer
中文意思是缓冲区。isBuffer
是用来判断 buffer
类的,它是一个类似于 Array
的对象。
这里先判断 val
是否为 null
或者 undefined
,再判断 val
的构造函数是否为 null
或者 undefined
,最后再回调 isBuffer
函数对 val
的构造函数进行判断。
isArrayBufferView
function isArrayBufferView(val) { let result; if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { result = ArrayBuffer.isView(val); } else { result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); } return result; }
isPlainObject
const isPlainObject = (val) => { if (kindOf(val) !== 'object') { return false; } const prototype = getPrototypeOf(val); return ( prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val ); };
isPlainObject
是用来判断纯对象的,纯对象可以理解为纯粹的对象。
isFormData
const isFormData = (thing) => { const pattern = '[object FormData]'; return thing && ( (typeof FormData === 'function' && thing instanceof FormData) || toString.call(thing) === pattern || (isFunction(thing.toString) && thing.toString() === pattern) ); }
isFormData
是判断传入的参数 thing
是否为 isFormData
。
trim
function trim(str) { return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); }
这个方法在项目中有用到过,但是用的频率并不是很高,是用来去除字符串两侧的空白字符的。
findKey
function findKey(obj, key) { key = key.toLowerCase(); const keys = Object.keys(obj); let i = keys.length; let _key; while (i-- > 0) { _key = keys[i]; if (key === _key.toLowerCase()) { return _key; } } return null; }
其实从字面意思也大概能猜到它的作用,它是用来找到对象的 Key
值的,也可以说是键值吧。
merge
function merge(/* obj1, obj2, obj3, ... */) { const {caseless} = isContextDefined(this) && this || {}; const result = {}; const assignValue = (val, key) => { const targetKey = caseless && findKey(result, key) || key; if (isPlainObject(result[targetKey]) && isPlainObject(val)) { result[targetKey] = merge(result[targetKey], val); } else if (isPlainObject(val)) { result[targetKey] = merge({}, val); } else if (isArray(val)) { result[targetKey] = val.slice(); } else { result[targetKey] = val; } } for (let i = 0, l = arguments.length; i < l; i++) { arguments[i] && forEach(arguments[i], assignValue); } return result; }
从参数里可以发现,它传入了很多对象参数,再结合 merge
合并的意思,不难猜出这个函数是用来合并对象的。在合并代码的时候,里面就能看到 merge
。
stripBOM
function stripBOM(content) { if (content.charCodeAt(0) === 0xFEFF) { content = content.slice(1); } return content; }
这个函数是用来去除编码中的 BOM
的,这个确实没怎么见过或者听说过。
endsWith
const endsWith = (str, searchString, position) => { str = String(str); if (position === undefined || position > str.length) { position = str.length; } position -= searchString.length; const lastIndex = str.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; }
从传入参数 str,searchString, position
来判断,这个函数应该和判断字符串位置有关。然后结合 lastIndex === position
可以看出,它的作用是判断字符串(str
)是否以指定的字符串(searchString
)结尾(position
)。
toArray
const toArray = (thing) => { if (!thing) return null; if (isArray(thing)) return thing; let i = thing.length; if (!isNumber(i)) return null; const arr = new Array(i); while (i-- > 0) { arr[i] = thing[i]; } return arr; }
这个函数可以将类数组转换为数组,里面的逻辑实现不难理解,相对比较简单。
toCamelCase
const toCamelCase = str => { return str.toLowerCase().replace(/[_-\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) { return p1.toUpperCase() + p2; } ); };
都知道驼峰命名法吧,这个函数可以将字符串转换为驼峰命名。类似于把 abcdef
的字符转换成 abcDef
。
总结
仅仅看一遍是远远不够的,这源码里覆盖了太多工具函数,这里我阅读了其中十几种。通过简单阅读了一遍 axios
的源码,让我对 axios
有了进一步认识,关于剩下的源码部分,下周会继续抽时间完成阅读学习。总之,我认为 axios
源码可以多看几遍,每一遍或许都会有不同的认识。
加载全部内容