您好,登錄后才能下訂單哦!
這篇文章主要講解了“JavaScript基礎函數和方法詳解”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“JavaScript基礎函數和方法詳解”吧!
一、函數和方法的區別
二、如何寫好一個函數
2.1 命名準確
2.1.1 函數命名
2.1.2 參數命名
2.2 函數注釋
2.2.1 參數注釋
2.3 函數參數
2.3.1 參數默認值
2.3.2 對象參數
2.3.3 參數數量
2.3.4 參數類型防御
2.4 函數的返回
2.4.1 冪等函數
2.4.2 純函數
2.4.3 return null
函數和方法的區別
函數(function):函數是帶有名稱和參數的 JavaScript 代碼段,可以一次定義多次調用。
方法(method):當將函數和對象寫在一起時,函數就變成了“方法”,比如當函數賦值給對象的屬性時,我們便稱其為“方法”。
在 JS 中,除了變量,用的最多的應該就是函數了,函數是 Javascript 的第一公民。
函數的命名需要明確,語義清晰,簡單概括函數的功能。我們不要想著代碼簡短而縮短函數名稱,這并不會提高什么性能或效率,相反,一個函數名稱若不夠清晰,往往其他人無法理解。
盡量使用動詞,比如:getXxxxx、setXxxxx,動詞在前面,語義就能更加清晰。
強調語義化,參數命名讓調用者更清晰的知道該傳入什么,對應什么參數。當然,像一些通用命名還是可接受的,像 callback,fn,即使不看注釋,往往我也知道這里的參數要做什么,傳什么。
/** * 時間格式化工具函數 * * @param { (Date | number) } date - 時間 * @param { string } unit - 轉換格式 */ export const timeFormat = (date: Date | number | string, unit: string) => { if (!date) { return '' } if (typeof date === 'string') return date; if (typeof date === 'number') { date = new Date(date); } const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const hour = date.getHours(); const minute = date.getMinutes(); const second = date.getSeconds(); if (unit === 'year') return `${year}`; if (unit === 'month') return `${year}-${month}`; if (unit === 'day') return `${year}-${month}-${day}`; if (unit === 'hour') return `${year}-${month}-${day} ${hour}`; if (unit === 'minute') return `${year}-${month}-${day} ${hour}:${minute}`; if (unit === 'second') return `${year}-${month}-${day} ${hour}:${minute}:${second}`; }
/** * 時間格式化工具函數 * * @param { (Date | number) } date - 時間 * @param { string } unit - 轉換格式 */
@param { type } 參數 - 參數解釋:type 表明的是參數的類型,比如 string,number,當有多個參數類型的時候,可以這么來標識 { (string|string[]) },表示這個參數可以是字符串或者字符串數組。
對象屬性:需要解釋對象的每一個屬性
/** * 將項目分配給員工的函數 * * @param {Object} employee - 項目員工 * @param {string} employee.name - 項目員工的姓名 * @param {string} employee.department - 項目員工的部門 */ Project.prototype.assign = function(employee) { // ... };
可選參數:
/** * 時間格式化工具函數 * * @param { (Date | number | string) } date - 時間 * @param { string } [unit] - 轉換格式 */ export const timeFormat = (date: Date | number | string, unit: string) => { // ... }
默認值:
/** * 時間格式化工具函數 * * @param { (Date | number) } date - 時間 * @param { string } [unit = 'second'] - 轉換格式 */ export const timeFormat = (date: Date | number | string, unit = 'second') => { // ... }
export const timeFormat = (date: Date, unit = 'second') => { // ... }
async function printer_proxy_print( html_str: string, file_path: string, device: string | undefined, orientation: number, printer_mode: string, width: number, height: number, scale: number, from: number, to: number, left_offset: number, top_offset: number, pdf_tools: string | undefined, begin_page = 1, end_page = 1, repeat_times = 1, print_type: string ) { // ... }
可以給參數默認值,這樣可以只傳前面幾個必要的參數,像這樣調用。
async function printer_proxy_print( html_str: string, file_path: string, device = 'pc', orientation = 'xxx', printer_mode = 'xxx', width = 123, height = 123, scale = 123, from = 123, to = 123, left_offset = 123, top_offset = 123, pdf_tools = 123, begin_page = 1, end_page = 1, repeat_times = 1, print_type = 'base64' ) { // ... } await printer_proxy_print(html_str, file_path);
上面的方法看似可行,實際上,當我中間某個參數不一樣的時候,我就需要把這個參數前面的參數都傳一遍。這樣顯然不可行。所以當參數多的時候,我們需要用對象解構的方式傳參。
async function printer_proxy_print({ html_str, file_path, device = 'pc', orientation = 'xxx', printer_mode = 'xxx', width = 123, height = 123, scale = 123, from = 123, to = 123, left_offset = 123, top_offset = 123, pdf_tools = 123, begin_page = 1, end_page = 1, repeat_times = 1, print_type = 'base64' }) { // ... } await printer_proxy_print({html_str, file_path});
解構的好處便是我可以隨便傳我想要的某幾個參數,而不用在意順序問題。不過像這么多參數的函數往往存在問題(具體問題具體分析)。也就是下面提到的參數數量問題。
一個函數的參數越少越好,最多不應該超過3個,參數多往往意味著關系多,邏輯交叉相對也就多了起來。在進行測試的時候,往往也就很難覆蓋到所有條件,出問題概率也就加大了。
參數多的時候,有時候也意味著功能多,就違背了 單一功能 的原則。
在 TS 開發前,我們不知道用戶會傳什么東西進來,這時候往往容易產生類型錯誤,又或者,我們想實現兼容,像前面的 timeFormat 函數,我們希望用戶調用的時候,可以是想對 時間對象 格式化,也可以是對 時間戳 格式化,那我們就需要做一個防御處理。
if (!date) { return '' } if (typeof date === 'string') return date; if (typeof date === 'number') { date = new Date(date); }
不過值得注意的是,即使我們用上了 TS,在大多數情況下,我們確實可以避免參數類型問題,但是這并不絕對,因為我們有時候會直接接受 接口 返回的數據。
我們常說,永遠不要相信用戶的輸入,同樣,接口返回的數據我也不信,我們不能保證,后端不會出錯,約定好的參數是數組類型,怎么空的時候,你給我個 null 呢?
當然這些情況有時候需要去試錯,有時候我們能想到的可能,不要偷懶,給寫上類型判斷吧。
什么叫冪等,簡單來說,輸入什么輸出什么是固定的,入參決定了出參,不管調用多少次,只要輸入一樣,結果應該保持一樣。
function sum(a: number, b: number) { return a + b; }
冪等函數具有可維護性,相對容易進行單元測試。
純函數在冪等的條件下,還要求沒有副作用。
const dog = { name: 'puppy', age: 2, weight: 30, } if (!dog.color) { console.log('has no color'); } function addColor(dog) { dog.color = 'white'; } addColor(dog); console.log(dog); // {name: "puppy", age: 2, weight: 30, color: "white"}
可以看到,addColor 函數修改了 dog 對象的屬性,也就是產生了副作用。
function addColor(dog) { let copyDog = Object.assign({}, dog); copyDog.color = 'white'; return copyDog; }
這樣一來,dog 對象的屬性就不會修改,addColor 函數是純函數。
null 在進行處理的時候相對麻煩,需要進行判斷,導致了額外的代碼,應當返回空對象,或者是空數組,或者拋出異常。
1)函數(function)是一段代碼,通過名字來進行調用。它能將一些數據(參數)傳遞進去進行處理,然后返回一些數據(返回值),也可以沒有返回值。
2)方法(method)是通過對象調用的javascript函數。也就是說,方法也是函數,只是比較特殊的函數。他是和一個對象相關聯。假設有一個函數是fn,一個對象是obj,那么就可以定義一個method:
obj.method = fn;
obj.method();
3)函數的數據是顯式傳遞
4)方法中的數據是隱式傳遞的;方法和對象相關。
感謝各位的閱讀,以上就是“JavaScript基礎函數和方法詳解”的內容了,經過本文的學習后,相信大家對JavaScript基礎函數和方法詳解這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。