這不是把大家帶到黑暗裡,而是把大家帶過黑暗,在黑暗裡檢驗一遍,再回到陽光底下,你會明白該如何面對生活。
Ang Lee
事實上,關於control flow的雷區,我們已經看過差不多了,接下來這幾天,我們會看看JS中還有什麼常見的地雷值得我們進一步探究。其實是我不知道怎麼分類。
今天,我們先來看看關於函式傳參,與函式返回資料。
假設我們有個函式postCustomer
,需要四個參數去創造一個新的消費者(透過API)。
// 可能會被討厭的寫法
// utility
function postCustomer(customerName, date, isAdmin, isPremiere) {
return fetch('https://url.of.api', {
method: 'POST',
body: JSON.stringify({
customerName, date, isAdmin, isPremiere
})
});
}
// usage
postCustomer('Ryvn', '2022-09-26', false, true);
在這個寫法中,最不清楚的就是最後兩的布林值,這使得我們必須回頭去看原本函式的內容。
一個更好的寫法,就是把引數arguments包在一個object裡面。
// 可能不會被討厭的寫法
// utility
function postCustomer({ customerName, date, isAdmin, isPremiere }) {
return fetch('https://url.of.api', {
method: 'POST',
body: JSON.stringify({
customerName, date, isAdmin, isPremiere
})
});
}
// usage
postCustomer({
customerName: 'Ryvn',
date: '2022-09-26',
isAdmin: false,
isPremiere: true,
});
因為在ES6中有object destructuring,所以我們只要單純的加上大括號即可。此時,我們只要記得在傳引數的時候,我們必須傳入一過與參數對應key值相關的object即可。
我們可以總結這種寫法的幾個好處(壞處就是要寫比較多的code):
有時候,我們希望某些參數是必要參數,有些則為非必要optional arguments。以上述例子為例,我們可以將前兩個參數customerName
與date
作為必要參數,剩下的作為非必要,這樣我們可以這樣寫:
// 可能不會被討厭的寫法
// optional arguments
// utility
function postCustomer(customerName, date, options) {
return fetch('https://url.of.api', {
method: 'POST',
body: JSON.stringify({
customerName,
date,
isAdmin: options ? !!options.isAdmin : false,
isPremiere: options ? !!options.isPremiere : false
})
});
}
// usage
postCustomer('Ryvn', '2022-09-26', {
isPremiere: true,
});
這種作法在NodeJS和許多開源libraries滿常見的。
返回值不一定是單一數值,更多時候是彼此相關的一個資料包。此時tuple是再適合不過了。
以下這個例子是想取得某DOM元素(這裡是ID)的大小,特別是左上角的x與y座標。
function getElementLeftTopPosition(elementID) {
const element = document.getElementById(elementID);
if (!element) {
return [NaN, NaN];
}
const rect = element.getBoundingClientRect();
return [rect.x, rect,y];
}
const [x ,y] = getElementLeftTopPosition('ryvn-element');
今天先這樣,明天我們再來細談export
。