Axios 可以使用物件和函式兩種方式呼叫,是因為它的核心 API 設計利用了函式過載和 JavaScript 的靈活性。 本質上,Axios 暴露的頂層 axios
物件既是一個函式,又是一個擁有屬性的物件。
以下是它的實現方式:
-
Axios 物件是一個函式: 當你像這樣呼叫
axios(config)
時,你實際上是在直接呼叫 Axios 物件本身。這個函式內部會處理配置config
,併發起請求。 -
Axios 物件擁有方法 (HTTP verbs):
axios.get(url[, config])
、axios.post(url[, data[, config]])
等方法是 Axios 物件的屬性。這些方法是對axios()
函式的封裝,它們預設了 HTTP 方法,並簡化了常見請求的呼叫方式。 例如,axios.get(url, config)
內部會呼叫axios({...config, method: 'get', url})
。 -
函式過載 (透過引數型別判斷):
axios()
函式內部會根據傳入引數的型別進行不同的處理。如果傳入的是一個配置物件config
,它會直接使用這個配置發起請求。如果傳入的是 URL 字串,它會將 URL 視為config.url
,並建立一個預設的 GET 請求配置。
// Simplified example of how axios might be implemented internally
function axios(configOrUrl, data, config) {
let finalConfig = {};
if (typeof configOrUrl === 'string') { // URL as first argument
finalConfig.url = configOrUrl;
finalConfig.method = 'get'; // Default to GET
if (data) { // Second argument is data if provided
finalConfig.data = data;
}
if (config) { // Third argument is config
finalConfig = { ...finalConfig, ...config };
}
} else if (typeof configOrUrl === 'object') { // Config object as first argument
finalConfig = { ...configOrUrl };
if (data) {
finalConfig.data = data; // Overwrite data if provided as second argument (less common)
}
} else {
throw new Error('Invalid arguments provided to axios');
}
// ... rest of the axios logic to make the request using finalConfig
return makeRequest(finalConfig);
}
// Adding HTTP verb methods to the axios object
axios.get = function(url, config) {
return axios({ ...config, method: 'get', url });
};
axios.post = function(url, data, config) {
return axios({ ...config, method: 'post', url, data });
};
// ... other HTTP verb methods (put, delete, patch, etc.)
// Example usage:
// Object style
axios({
method: 'post',
url: '/user/12345',
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
});
// Function style (GET)
axios('/user/12345').then(response => { /* ... */ });
// Function style (POST) - less common, can be confusing
axios('/user/12345', { firstName: 'Fred' }).then(response => { /* ... */ });
// Using convenience methods
axios.get('/user/12345').then(response => { /* ... */ });
axios.post('/user/12345', { firstName: 'Fred' }).then(response => { /* ... */ });
透過這種巧妙的設計,Axios 提供了靈活的 API,開發者可以根據自己的喜好和需求選擇不同的呼叫方式。 使用物件方式可以進行更精細的配置,而使用函式方式則更加簡潔方便。