iT邦幫忙

2023 iThome 鐵人賽

DAY 17
0
自我挑戰組

JavaScript 是什麼?可以吃嗎?系列 第 17

Day17 - 標準化你的函數參數 - Parameter Normalization

  • 分享至 

  • xImage
  •  

嗨大家好,我是 Eric!今天我要跟大家講一個非常有用但又常被忽略的技巧,那就是「參數歸一化」或「Parameter Normalization」,我們都知道在 JavaScript 中,函數是第一類物件,這意味著可以把函數當作參數傳遞,或者做為返回值。但是,當一個函數有多個參數、多種調用方式時,管理這些參數就變得非常繁瑣。

舉個例子,假設我們有一個 formatDate(date, format, isPad = false) 函數,用來格式化日期。這個函數有三個參數:

  1. date:需要格式化的日期。
  2. format:日期的格式。
  3. isPad:是否需要在日期的數字前面補零,預設是 false

這個函數可以有多種調用方式,比如只傳遞日期,或者傳遞日期和格式等。這時,我們如何有效地管理這些參數,使函數調用變得簡單而不失靈活性?

參數歸一化

參數歸一化的目的是將多種可能的函數參數或調用方式統一為一個標準形式,這樣在函數內部就可以更簡單、更一致地處理參數。

// 進行格式化規則的歸一化function 
_formatNormalize(formatter) {
	// 如果 formatter 是一個函數,則直接返回
	if (typeof formatter === 'function') {
      return formatter;
  }
	// 如果 formatter 不是字符串也不是函數,拋出類型錯誤
	if (typeof formatter !== 'string') {
      throw new TypeError('formatter must be string or function');
  }

	// 給定預設的日期和時間格式
	if (formatter === 'date') {
      formatter = 'yyyy-MM-dd';
  }
  else if (formatter === 'datetime') {
      formatter = 'yyyy-MM-dd HH:mm:ss';
  }

	// 創建一個 formatterFunc 來進行實際的格式化操作
	const formatterFunc = (dateInfo) => {
    const { yyyy, MM, dd, HH, mm, ss, ms } = dateInfo;
    return formatter
        .replaceAll('yyyy', yyyy)
        .replaceAll('MM', MM)
        .replaceAll('dd', dd)
        .replaceAll('HH', HH)
        .replaceAll('mm', mm)
        .replaceAll('ss', ss)
        .replaceAll('ms', ms);
  }

	// 返回這個新創建的 formatterFunc
	return formatterFunc;
}

// 主函數:用於日期的格式化function 
formatDate(date, formatter, isPad = false) {
	// 使用 _formatNormalize 來獲得實際應用的 formatter
  formatter = _formatNormalize(formatter);

	// 獲取日期的各個部分
	const dateInfo = {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    day: date.getDate(),
    hour: date.getHours(),
    minute: date.getMinutes(),
    second: date.getSeconds(),
    millisecond: date.getMilliseconds(),
  };

	// 轉換為字符串
	dateInfo.yyyy = dateInfo.year.toString();
	dateInfo.MM = dateInfo.month.toString();
	dateInfo.dd = dateInfo.day.toString();
	dateInfo.HH = dateInfo.hour.toString();
	dateInfo.mm = dateInfo.minute.toString();
	dateInfo.ss = dateInfo.second.toString();
	dateInfo.ms = dateInfo.millisecond.toString();
	
	function _isPad(prop, len){
    dateInfo[prop] = dateInfo[prop].padStart(len, '0');
	};

	// 補零操作
	if (isPad) {
    _isPad('yyyy', 4);
    _isPad('MM', 2);
    _isPad('dd', 2);
    _isPad('HH', 2);
    _isPad('mm', 2);
    _isPad('ss', 2);
    _isPad('ms', 3);
	}

	// 進行實際的格式化操作
	const result = formatter(dateInfo);
  return result;
}

這樣做的好處是:

  1. 函數調用更加靈活:你可以選擇只傳入必要的參數,也可以傳入所有參數
  2. 代碼可讀性更強:透過 _formatNormalize,我們簡化了 formatter 的多種可能形式,使得 formatDate 函數更加整潔和一致
  3. 方便後期維護:如果未來需要添加更多參數,你只需在 dateInfo 物件中添加,而不需要修改函數的簽名

總結

今天我們講了參數歸一化的重要性,特別是在有多個參數和多種調用方式的情況下。透過一個實際的 formatDate 函數例子,我們看到如何利用參數歸一化來簡化函數的內部邏輯,使其更加靈活和易於維護

重點是:不管你的函數有多少參數或多少種調用方式,參數歸一化都能幫你簡化問題,提高代碼的可讀性和可維護性

那麼今天的分享就到這邊~我們明天見~


上一篇
Day16 - 表單的元素選擇:為什麼我們應該用 Form 而不是 Div?
下一篇
Day18 - 使用 Audio API 實現音頻視覺化
系列文
JavaScript 是什麼?可以吃嗎?20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言