Understanding Axios' Two Invocation Methods and Its Underlying Implementation
This article explains the two ways to call Axios—using a configuration object or shortcut methods—then walks through building a minimal Axios clone, detailing its constructor, prototype methods, and the clever instance creation that lets the library behave both as a function and an object.
Two Invocation Methods of Axios
Developers who frequently call APIs are likely familiar with the two usage patterns of Axios:
axios(config)
// Configuration style request
axios({
method: 'post',
url: '/user/12345',
});axios.post(url, config)
// Concise style
axios.post('/user/12345');You might wonder: what exactly is Axios, why can we use these two ways to request, and how is it designed?
Brief Analysis of Axios Principles
To answer these questions we first implement a simple version of Axios by mimicking its source code.
Write a Simple Axios
Create a Constructor Function
function Axios(config){
this.defaults = config; // configuration object
this.interceptors = { // interceptor object
request:{},
response:{}
}
}The code above defines a basic Axios class but it has no functionality yet. Next we add methods.
Add Methods on the Prototype
Axios.prototype.request = function(config){
console.log('Sending Ajax request type:' + config.method)
}
Axios.prototype.get = function(){
return this.request({method:'GET'})
}
Axios.prototype.post = function(){
return this.request({method: 'POST'})
}Here request is a generic request method, while get and post simply call request with different HTTP methods, mirroring the behavior of axios(config) and axios.post() .
Now we create an instance:
let axios = new Axios(config);The created object contains defaults and interceptors properties, and its prototype ( __proto__ ) holds request , get , and post . Thus we can call axios.post() to simulate an API request.
However, at this point axios is just an object, not a function, so we cannot invoke it as axios(config) .
The Genius Idea in Axios
To allow both axios(config) and axios.get() , Axios uses a clever instance creation pattern:
function createInstance(config) {
// Note: instance is a function
const instance = Axios.prototype.request;
instance.get = Axios.prototype.get;
instance.post = Axios.prototype.post;
return instance;
}
let axios = createInstance();In this pattern, instance is a function (the request method) that also carries the shortcut methods as its own properties, making the library callable both as a function and as an object.
Because instance is a function, axios(config) works.
Because instance also has get and post properties, axios.get() and axios.post() work.
Axios Source Code Implementation
function createInstance(config) {
// Instantiate an object
var context = new Axios(config); // cannot be used directly as a function
var instance = Axios.prototype.request.bind(context);
// Add prototype methods to the instance so it has get, post, request, etc.
Object.keys(Axios.prototype).forEach(key => {
instance[key] = Axios.prototype[key].bind(context);
})
// Add instance properties (defaults, interceptors)
Object.keys(context).forEach(key => {
instance[key] = context[key];
})
return instance;
}This code binds the request method to the newly created context object, then copies all prototype methods and instance properties onto the function, resulting in an object that is both callable and enriched with shortcut methods.
Note the importance of binding this correctly; without binding, Axios.prototype.request() would have an incorrect this reference and fail.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.