- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
- 这是源码共读的第19期,链接:juejin.cn/post/708311…。
趁着还没开始忙起来 多看点源码,今天进行第二篇源码阅读 axios 工具函数
曾经粗略过过一遍 axios 源码,但是印象已然模糊,这里先根据内容安排先再过一遍 axios 的工具函数
了解到了开源项目中比较重要的文档,CONTRIBUTING.md,表明了如何为 Axios 项目做贡献 其中比较重要的是代码规范 node style guide. 和行为准则 Contributor Covenant Code of Conduct
首先我们遇到第一个函数 —— Object.prototype.toString
toString()方法可以改写,以实现对对象更为具体的描述
下面从所有的工具函数中挑选几个进行解读:
isArray
现阶段源码使用了 Array.isArray() 来替代原先的判断方式 toString.call(val) === '[object Array]'
isBuffer
我们要了解下这里的 Buffer 指的是什么 在 Node.js 中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。 www.runoob.com/nodejs/node…
function isBuffer(val) {
return val !== null
&& !isUndefined(val)
&& val.constructor !== null
&& !isUndefined(val.constructor)
&& typeof val.constructor.isBuffer === 'function'
&& val.constructor.isBuffer(val);
}
isArrayBufferView
什么是 arrayBuffer
isPlainObject
判断目标对象的原型是不是null 或 Object.prototype
纯对象:用{}或 new Object()创建的对象。 那么通过 Object.create(null) 创建的对象呢。
isStream
isURLSearchParams
URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。
forEach
集成了 Array 和 Object 的遍历; 对不可迭代对象,先将其包裹成 Array
Object.prototype.hasOwnProperty: 返回一个布尔值,指示对象自身属性中是否具有指定的属性(可枚举、不可枚举均可)
for...in 循环只会遍历可枚举属性
/**
* 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
*/
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);
}
}
}
}
merge
将多个对象进行合并,键相同则使用排在后面的对象中的值
递归调用
小技巧: array.slice() 浅拷贝数组
/**
* 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;
}
extend
将 b 对象上的属性扩展到 a 对象上,并返回 a 对象
/**
* Extends object a by mutably adding to it the properties of object b.
*
* @param {Object} a The object to be extended
* @param {Object} b The object to copy properties from
* @param {Object} thisArg The object to bind function to
* @return {Object} The resulting value of object a
*/
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;
}
Axios 的工具函数源码还是比较简单,但是代码编写风格还是有值得学习借鉴的地方。 通过本次源码阅读,发现了知识点上的一些遗忘,借此机会再好好复习一下。
- To Do:
- axios 全部源码,这些工具函数都在那里调用了,起到了什么作用
- js 基础
- 函数调用的几种方式复习,包括 call apply bind
- instance of / typeof
- 文件类型
- blob 文件流类型 参考文章