■ 查看源码发现,起初axios【instance=bind(Axios.prototype.request, context);】是一个函数,
但后续【 utils.extend(instance, Axios.prototype, context);】又给它添加上了一些方法属性。
✿ axios 函数对象可以调用自身axios(config)
发送请求也可以调用属性的方法axios.request(config)
发送请求的原理:(看学习axios必知必会(2)https://www.cnblogs.com/shan333/p/15836026.html)
一、源码分析axios的创建
1、查看axios的实例对象new Axios(defaultConfig);
① 在类Axios 发现有配置对象和拦截器对象属性
② 在Axios.js 文件中,还发现Axios的原型:Axios.prototype动态添加了属性方法
request,getUri,
'delete', 'get', 'head', 'options',
'post', 'put', 'patch'
■ axios的创建的源码:
// 通过配置创建 axios 函数
var axios = createInstance(defaults);
function createInstance(defaultConfig) {
//创建一个实例对象 context 可以调用 get post put delete request
var context = new Axios(defaultConfig);// context 不能当函数使用
……
}
//在 Axios 类内有属性 配置对象和拦截器对象
function Axios(instanceConfig) {
//实例对象上的 defaults 属性为配置对象
this.defaults = instanceConfig;
//实例对象上有 interceptors 属性用来设置请求和响应拦截器
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
// 在Axios.js 文件中,还发现:
Axios.prototype.request = function request(config) {
……
}
Axios.prototype.getUri = function getUri(config) {
……
}
utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function (url, config) {
……
}
}
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
/*eslint func-names:0*/
Axios.prototype[method] = function (url, data, config) {
……
}
}
2、接着是instance:
首先是通过方法bind将request方法赋值给instance(此时instance是一个函数变量);
然后,通过方法extends 将Axios.prototype 上的方法添加到 instance身上(此时instance是一个
“函数对象”变量);还将实例对象content的属性(配置对象和拦截器对象属性)添加到instance身上
■ axios的创建的源码:
function createInstance(defaultConfig) {
//创建Axios的实例对象 context
var context = new Axios(defaultConfig);//context 是实例对象,不能当函数使用
//将request 方法的 this 指向 context 并返回新函数 (instance 与 Axios.prototype.request 代码一致)
var instance = bind(Axios.prototype.request, context); //instance是函数,可以用作函数使用
//将Axios的原型 Axios.prototype 的方法都添加到 instance 函数身上
utils.extend(instance, Axios.prototype, context); //instance是"函数对象",可当函数使用,也可当对象使用
//将实例对象content的方法和属性添加到 instance 函数身上
utils.extend(instance, context);
return instance;
}
■ bind函数:
//返回一个新的函数,并将新函数 this 绑定到一个对象身上
module.exports = function bind(fn, thisArg) {
return function wrap() {
var args = new Array(arguments.length);
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i];
}
return fn.apply(thisArg, args);
};
};
■ extend函数:
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的创建
❀ 实现调用axios(config)自身发送请求、调用axios对象的方法属性 axios.request(config)发送请求