js 函數參數推薦書寫方式 ({ param1, param2, ... })
編程語言函數(包括對象的方法)參數的取值方式大致可以分爲兩種:按序取值與按名取值。
一般編程語言都是按序取值,比如 C、Java、JavaScript 等,少數語言支持按名取值,比如 Groovy。
1. 按序取值
按照順序,挨個取值,每個參數的順序是固定的。
const func = (param1, param2, ...) => { ... }
func(1, 2, ...)
2. 按名取值
按照名稱取值,可以任意安排各個參數的順序。
以下語法並不存在,只是作爲講解生造的
const func = (param1: value1, param2: value2, ...) => { ... }
func(param1: 1, param2: 2); // ok
func(param2: 2, param1: 1); // ok again
3. js 的按名取值
JavaScript 語言本身並不支持按名取值,但結合 ES6 的解構賦值,可以模擬函數參數的按名取值。
const func = ({ param1, param2, ... }) => { ... }
func({ param1: 1, param2: 2, ... });
但這種方式如果不傳參數調用 func()
就會報錯,需要 func({})
這樣調用才表示什麼參數都不傳。
爲了兼容這種方式,可以這樣做:
const func = ({ param1, param2, ... } = {}) => { ... }
func(); // ok
func({}); // ok again
4. 爲什麼推薦使用按名取值的方式
按名取值最大的好處是可以隨意安排參數的順序,有利於擴展,特別是對 API 接口來說。
比如:
export const dialog = (title, content, confirmCallback, cancelCallback) => { ... }
比如上面的函數中,大部分情況下我只用 content, confirmCallback
,那麼我就需要這樣做:
dialog(null, 'content', () => { ... });
如果我需要擴展一個參數 icon
, 那麼爲了兼容以前的版本,我只能加在最後面:
export const dialog = (title, content, confirmCallback, cancelCallback, icon) => { ... }
現在,大部分情況下我只用 content, confirmCallback, icon
,那麼我就需要這樣做:
dialog(null, 'content', () => { ... }, null, 'icon');
如此,便很麻煩,不利於擴展。
如果使用按名取值的方式,便迎刃而解:
export const dialog = ({title, content, confirmCallback, cancelCallback} = {}) => { ... }
// 擴展 icon
export const dialog = ({title, content, icon, confirmCallback, cancelCallback} = {}) => { ... }
dialog({content: 'content', confirmCallback: () => { ... }});
dialog({content: 'content', icon: 'icon', confirmCallback: () => { ... }});
5. 大家可能的反駁
有人可能會說,可以這樣做:
export const dialog = (title, content, confirmCallback, cancelCallback) => {
if (typeof content === 'function') {
cancelCallback = confirmCallback;
confirmCallback = content;
content = title;
}
...
}
對於這種方式,我只想說:兄弟,簡潔一點不好嗎?
後續
更多博客,查看 https://github.com/senntyou/blogs
版權聲明:自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證)