axios源码分析--基础工具函数
2022/1/14 1:03:51
本文主要是介绍axios源码分析--基础工具函数,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.目标
学习axios源码中实用的工具函数
2.源码分析
2.1 isArray 判断数组
var toString = Object.prototype.toString; // 通过Object.prototype.toString来获取每个对象的类型 function isArray(val) { return toString.call(val) === '[object Array]'; }
2.2 isUndefined 判断Undefined
// 如果要判断是否是null,使用Object.prototype.toString function isUndefined(val) { return typeof val === 'undefined'; }
2.3 isBuffer 判断Buffer
// a.判断val不是null和undefined // b.因为Buffer本身是一个类,所以要判断它是否存在构造函数 // c.通过自身的isBuffer判断 // 在node中使用,Buffer.from('a') function isBuffer(val) { return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val); }
2.4 isArrayBuffer 判断ArrayBuffer
var toString = Object.prototype.toString; function isArrayBuffer(val) { return toString.call(val) === '[object ArrayBuffer]'; }
2.5 isFormData 判断FormData
// 先判断typeof FormData !== 'undefined',猜测原因是为了兼容IE,相关链接:https://stackoverflow.com/questions/19486597/formdata-is-undefined-in-ie-only function isFormData(val) { return (typeof FormData !== 'undefined') && (val instanceof FormData); }
2.6 isArrayBufferView判断ArrayBufferView
function isArrayBufferView(val) { var result; // 此处主要是为了兼容IE9及以下 if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { result = ArrayBuffer.isView(val); } else { result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); } return result; }
2.7 isString判断String
function isString(val) { return typeof val === 'string'; }
2.8 isNumber判断Number
function isNumber(val) { return typeof val === 'number'; }
2.9 isObject判断Object
// 看了下测试用例,数组也算对象,如果真实只检测object的话,还建议使用 Object.prototype.toString function isObject(val) { return val !== null && typeof val === 'object'; }
2.10 isPlainObject判断PlainObject
// plainObject翻译为中文即为纯对象,所谓的纯对象,就是该对象是通过{}或new Object()创建的。 // 判断是否为“纯对象”,是为了和其他对象区分开比如说null、数组以及宿主对象(所有的DOM和BOM都是数组对象)等。 // 其实就是判断目标对象的原型是不是`null` 或 `Object.prototype // jQuery中的isPlainObject() 函数用于判断指定参数是否是一个纯粹的对象,返回值为Boolean类型。 //“纯粹的对象”,就是通过 { }、new Object()、Object.create(null) 创建的对象。 //这个方法的作用是为了跟其他的 JavaScript对象如 null,数组,宿主对象(documents),DOM 等作区分,因为这些用 typeof 都会返回object。 var toString = Object.prototype.toString; function isPlainObject(val) { if (toString.call(val) !== '[object Object]') { return false; } // Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值) // Object.getPrototypeOf:实际上其实是获取当前对象的__proto__ // Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 var prototype = Object.getPrototypeOf(val); // Object.getPrototypeOf({}.__proto__) // Object.create(null) return prototype === null || prototype === Object.prototype; } // 测试用例 // expect(utils.isPlainObject({})).toEqual(true); // expect(utils.isPlainObject([])).toEqual(false); // expect(utils.isPlainObject(null)).toEqual(false); // expect(utils.isPlainObject(Object.create({}))).toEqual(false); // let b = {} // expect(utils.isPlainObject(b).toEqual(true);
2.11 isDate判断Date
function isDate(val) { return toString.call(val) === '[object Date]'; }
2.12 isFile判断File
function isFile(val) { return toString.call(val) === '[object File]'; }
2.13 isBlob判断Blob
function isBlob(val) { return toString.call(val) === '[object Blob]'; }
2.14 isFunction判断Function
function isFunction(val) { return toString.call(val) === '[object Function]'; }
2.15 isStream判断Stream
function isStream(val) { // pipe是stream的一个方法,fs.createReadStream源码会使用到, return isObject(val) && isFunction(val.pipe); }
2.16 isURLSearchParams判断URLSearchParams
// URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串 // var paramsString = "q=URLUtils.searchParams&topic=api" //var searchParams = new URLSearchParams(paramsString); //searchParams.has("topic") === true; // true //searchParams.get("topic") === "api"; // true //searchParams.getAll("topic"); // ["api"] //searchParams.get("foo") === null; // true //searchParams.append("topic", "webdev"); //searchParams.toString(); // "q=URLUtils.searchParams&topic=api&topic=webdev" //searchParams.set("topic", "More webdev"); //searchParams.toString(); // "q=URLUtils.searchParams&topic=More+webdev" //searchParams.delete("topic"); //searchParams.toString(); // "q=URLUtils.searchParams" function isURLSearchParams(val) { return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; }
2.17 trim方法
function trim(str) { return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); }
2.18 判断是否事标准浏览器
/** * Determine if we're running in a standard browser environment * * This allows axios to run in a web worker, and react-native. * Both environments support XMLHttpRequest, but not fully standard globals. * * web workers: * typeof window -> undefined * typeof document -> undefined * * react-native: * navigator.product -> 'ReactNative' * nativescript * nativescript介绍 https://zhuanlan.zhihu.com/p/29452684 * navigator.product -> 'NativeScript' or 'NS' */ function isStandardBrowserEnv() { if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')) { return false; } return ( typeof window !== 'undefined' && typeof document !== 'undefined' ); }
2.19 重写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. * // 在迭代数组和对象的每一项时,执行传入的自定义方法 // 如果obj是数组,callback执行参数为value, index, and complete array // 如果obj是对象,callback执行参数为value, key, and complete object // 此覆盖方法貌似只是比forEach能多处理下对象类型,没太想到其他用途 function forEach(obj, fn) { // Don't bother if no value provided if (obj === null || typeof obj === 'undefined') { return; } // 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 (var i = 0, l = obj.length; i < l; i++) { fn.call(null, obj[i], i, obj); } } else { // Iterate over object keys for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { fn.call(null, obj[key], key, obj); } } } }
2.20 merge方法
/** * Accepts varargs expecting each argument to be an object, then * immutably merges the properties of each object and returns result. * * When multiple objects contain the same key the later object in * the arguments list will take precedence. * * Example: * * ```js * var result = merge({foo: 123}, {foo: 456}); * console.log(result.foo); // outputs 456 * ``` * * @param {Object} obj1 Object to merge * @returns {Object} Result of all merge properties */ function merge(/* obj1, obj2, obj3, ... */) { var result = {}; function assignValue(val, key) { if (isPlainObject(result[key]) && isPlainObject(val)) { result[key] = merge(result[key], val); } else if (isPlainObject(val)) { result[key] = merge({}, val); } else if (isArray(val)) { result[key] = val.slice(); } else { result[key] = val; } } for (var i = 0, l = arguments.length; i < l; i++) { forEach(arguments[i], assignValue); } return result; }
2.21 extend方法
/** * Extends object a by mutably adding to it the properties of object b. */ function extend(a, b, thisArg) { forEach(b, function assignValue(val, key) { if (thisArg && typeof val === 'function') { a[key] = bind(val, thisArg); } else { a[key] = val; } }); return a; }
2.22 stripBOM方法
/** * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) */ // 确定json文件是UTF-8 无BOM编码的的。如果有BOM,会在读取第一行的时候出现乱码。 // 所谓 BOM,全称是Byte Order Mark,它是一个Unicode字符,通常出现在文本的开头,用来标识字节序。UTF-8主要的优点是可以兼容ASCII,但如果使用BOM的话,这个好处就荡然无存了。 // 删除UTF-8编码中BOM function stripBOM(content) { if (content.charCodeAt(0) === 0xFEFF) { content = content.slice(1); } return content; }
3.知识扩展
3.1 判断数据类型的几种方式
// 数组最好使用typeof判断,这样定义()=> {}的方法,会被Object.prototype.toString识别为Object 1.typeof:仅能判断基础数据类型,如:“number”,”string”,”undefined”,”boolean”,“symbol” (ES6新增)六种,”object”类型建议使用Object.prototype.toString判断 2.instanceof 用于判断一个变量是否某个对象的实例,如:Object Array Function // 所有的均可使用下边方法判断 3.Object.prototype.toString:对于数组、null、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串。所以用此方法来判断
3.2 Buffer相关知识
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
3.3 NodeJS中ArrayBuffer与Buffer的异同
- ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区,是一个字节数组,可读但不可直接写。
- Buffer 是 Node.JS 中用于操作 ArrayBuffer 的视图,是 TypedArray的一种。
4.总结
附:
1.源码链接
这篇关于axios源码分析--基础工具函数的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12Axios库资料:新手入门必读教程
- 2024-11-11Axios库项目实战:新手入门教程
- 2024-09-29Axios库教程:初学者必备指南
- 2024-08-29Axios库资料:新手入门指南与基本使用教程
- 2024-03-14system bios shadowed
- 2024-03-14gabios
- 2024-02-07iOS应用提交上架的最新流程
- 2024-02-06打包 iOS 的 IPA 文件
- 2023-12-07uniapp打包iOS应用并通过审核:代码混淆的终极解决方案 ?
- 2023-11-25uniapp IOS从打包到上架流程(详细简单) 原创