创建 axios 实例
我们在根目录下创建axios.js
文件,文件内容如下面代码所示。
我们通过createInstance
函数创建一个axios
实例,该函数的核心是通过bind
方法把Axios
原型上的 request
方法,封装到instance
中,通过对 instance 函数的调用,间接调用 request
方法。js
中由于函数也是对象,所以我们可以把Axios
原型上的方法拷贝到该函数上,这样就可以实现例如axios.get()
这样的请求调用,当然现在原型上只有request
方法,我们之后会往上面扩展get
、post
等方法
"use strict";
var utils = require("./utils");
var bind = require("./helpers/bind");
var Axios = require("./core/Axios");
var defaults = require("./defaults");
/**
* 创建一个 Axios 实例
*
* @param {Object} defaultConfig 实例的默认配置
* @return {Axios} Axios的新实例
*/
function createInstance(defaultConfig) {
var context = new Axios(defaultConfig);
// bind方法返回一个新的函数,即instance
// instance接收到的任意参数,被传入到request方法中
var instance = bind(Axios.prototype.request, context);
// 把Axios.prototype上的方法绑定到context上下文中,并把这些方法拷贝到 instance 上
// 比如:会把 Axios.prototype.request 方法拷贝到 instance.request 中
utils.extend(instance, Axios.prototype, context);
// 把Axios实例即context上的属性拷贝到instance上
// 比如 instance.key = context.key
utils.extend(instance, context);
return instance;
}
// 创建被导出的默认实例
var axios = createInstance(defaults);
// 导出Axios类被用户继承使用
axios.Axios = Axios;
module.exports = axios;
module.exports.default = axios;
我们在helpers
目录下创建bind.js
文件,在该文件中实现 bind 函数
bind
函数需要传入两个参数
- fn 要执行的回调函数
- thisArg
fn
的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);
};
};
我们在 utils.js
中实现extend
方法
extend
方法接收三个参数
- a 对象类型,要被扩展的对象
- b 对象类型,需要把该对象上的属性拷贝到 a 对象上
- thisArg 可选参数,如果存在,把 b 对象上的方法的
this
上下文绑定到该参数
var bind = require("./helpers/bind");
function extend(a, b, thisArg) {
// 把b参数的属性拷贝到a参数上
forEach(b, function assignValue(val, key) {
// thisArg存在(即上下文存在),val为函数,我们把val的上下文绑定到thisArg
if (thisArg && typeof val === "function") {
a[key] = bind(val, thisArg);
} else {
// thisArg不存在,val可以是任意类型
a[key] = val;
}
});
return a;
}
module.exports = {
isArray,
forEach: forEach,
trim: trim,
extend: extend,
};