前言
Axios 是一个非常流行的库,它可以让你简单、方便地发送 HTTP 请求。它可以用在浏览器和 node.js 中,并且支持跨域请求。在 Github 上拥有快接近 10w 颗星了,可见其受欢迎程度。下面就来学习一下axios工具函数的源码。
准备工作
将项目克隆到本地后,安装依赖,执行:
npm start
打开浏览器访问 axios|Sandbox
页面,在浏览器的开发者模式下调试代码,如图:
工具函数概览
axios 的源码中提供了如下46个工具函数:
export default {
isArray,
isArrayBuffer,
isBuffer,
isFormData,
isArrayBufferView,
isString,
isNumber,
isBoolean,
isObject,
isPlainObject,
isUndefined,
isDate,
isFile,
isBlob,
isRegExp,
isFunction,
isStream,
isURLSearchParams,
isTypedArray,
isFileList,
forEach,
merge,
extend,
trim,
stripBOM,
inherits,
toFlatObject,
kindOf,
kindOfTest,
endsWith,
toArray,
forEachEntry,
matchAll,
isHTMLForm,
hasOwnProperty,
hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection
reduceDescriptors,
freezeMethods,
toObjectSet,
toCamelCase,
noop,
toFiniteNumber,
findKey,
global: _global,
isContextDefined,
toJSONObject
};
大致可分为以下几类:
- 类型判断
- 数据转换
- 数据查询
下面将挑选不同类别的几个工具函数进行解析。
源码解析
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 函数是一个用于确定 JavaScript 值类型的实用工具。它使用 toString 方法获取值类型的字符串表示形式,然后将该字符串映射到更易读的类型名称。该函数使用一个缓存对象来存储映射的类型名称.
下面是一个如何使用 kindOf 函数的示例:
kindOf(123); // 'number'
kindOf('hello world'); // 'string'
kindOf(true); // 'boolean'
kindOf([1, 2, 3]); // 'array'
kindOf({ name: 'John Doe' }); // 'object'
需要注意的是,kindOf 函数只用于确定基本值(如数字、字符串和布尔值)的类型和一些内置类型(如数组和对象)。
forEach
/**
* Iterate over an Array or an Object invoking a function for each item.
*
* If `obj` is an Array callback will be called passing
* the value, index, and complete array for each item.
*
* If 'obj' is an Object callback will be called passing
* the value, key, and complete object for each property.
*
* @param {Object|Array} obj The object to iterate
* @param {Function} fn The callback to invoke for each item
*
* @param {Boolean} [allOwnKeys = false]
* @returns {any}
*/
function forEach(obj, fn, {allOwnKeys = false} = {}) {
// Don't bother if no value provided
if (obj === null || typeof obj === 'undefined') {
return;
}
let i;
let l;
// Force an array if not already something iterable
if (typeof obj !== 'object') {
/*eslint no-param-reassign:0*/
obj = [obj];
}
if (isArray(obj)) {
// Iterate over array values
for (i = 0, l = obj.length; i < l; i++) {
fn.call(null, obj[i], i, obj);
}
} else {
// Iterate over object keys
const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
const len = keys.length;
let key;
for (i = 0; i < len; i++) {
key = keys[i];
fn.call(null, obj[key], key, obj);
}
}
}
手动实现了一个forEach循环,接收三个参数,第一个参数是所要遍历的对象,可以是数组或者是一个对象,第二个参数是每个参数所要执行的函数。
当遍历的是个对象时,第三个参数,用于标识,是使用 Object.getOwnPropertyNames(obj)
还是 Object.keys(obj)
获取对象的键,他们的区别在于 getOwnPropertyNames 能够获取对象的不可枚举属性。
toJSONObject
源码:
const toJSONObject = (obj) => {
const stack = new Array(10);
const visit = (source, i) => {
if (isObject(source)) {
if (stack.indexOf(source) >= 0) {
return;
}
if(!('toJSON' in source)) {
stack[i] = source;
const target = isArray(source) ? [] : {};
forEach(source, (value, key) => {
const reducedValue = visit(value, i + 1);
!isUndefined(reducedValue) && (target[key] = reducedValue);
});
stack[i] = undefined;
return target;
}
}
return source;
}
return visit(obj, 0);
}
这是一个将对象转换为 JSON 格式的方法。
toJSONObject 函数接受一个对象,使用递归遍历输入对象的 vist 函数。vist 函数检查对象中的每个值是否是对象,如果是,则将其添加到堆栈中。如果对象具有 toJSON 属性,则不将其添加到堆栈中。否则,该函数将创建一个新的 JavaScript 对象,并使用输入对象的属性和值填充该对象。如果属性值是一个对象,则递归地调用 vist 函数来处理该值。这个过程一直持续到处理完输入中的所有对象并将其添加到结果 JavaScript 对象为止。
总结
很多工具函数在功能和实现上都大同小异,不同的是要根据自己的目的和需求去编写工具函数,同时我们在开发中也要多总结思考,不能只是照搬别人的代码,可以参考优秀的源码再结合自己实际的需求,创造自己的工具函数。
标签:axios,obj,函数,对象,共读,Object,源码,kindOf,const From: https://blog.51cto.com/codeniu/6192223