Thinking--函數強制參數

Thinking系列,旨在利用10分鐘的時間傳達一種可落地的編程思想。

  • 默認值的作用
  • reduce 達到 map + filter 效果

JavaScript 是弱類型語言,對於函數的參數不會做強制限制,如果需要限制,我們如何處理?

實現

if 判斷

對於一些必須參數,我們通常採用 if 判斷,給出相關警告。

function test (name) {
	if (!name) {
		throw new Error('Missing parameter!') 
	}
	// ...
}

上述可以做到限制,但是不夠優雅,特別是多個必須參數時,代碼會變得冗長!

默認值

使用默認參數方式,如果未傳遞,則執行默認函數,給出告警。

// 默認參數模板函數
function requiredParam () {
  throw new Error('Missing parameter!') 
}

function test (name = requiredParam()) {
  // ...
}

注意: 傳入參數爲 undefined 或者不傳入的時候會使用默認參數;但是傳入 null 還是會覆蓋默認參數。

上述,requiredParam 可以傳入當前形參名稱,便於更加友好和針對性告警。

延伸一下,如果不傳遞形參名稱,如何動態獲取函數的形參呢?

獲取形參名稱

toString() 會返回函數源代碼的字符串,然後正則匹配、提取相關形參。

/* 代碼並不完善,箭頭函數、匿名函數情況均爲處理 */
function getArgs(func) {
  // 1. 首先匹配函數括弧裏的參數
  var args = func.toString().match(/function\s.*?\(((?<=\([^\)]*).*)\)/)[1]
  // 2. 分解參數成數組
  return args.split(",")
    .map(arg => arg.replace(/\/\*.*\*\//, "").trim())	 // 3. 去空格和內聯註釋
    .filter(arg => arg)	// 4. 沒有參數,返回空數組,而不是[""]
}

getArgs(test) // ["name = requiredParam()"]

上述 filter 是爲了確保沒參數的函數正常返回值 [''].filter(name => name) // []

reduce

上面執行了map,然後 filter,兩次循環。可以通過 reduce 方法同時實現 map + filter

function getArgs(func) {
  // 1. 首先匹配函數括弧裏的參數
  var args = func.toString().match(/function\s.*?\(((?<=\([^\)]*).*)\)/)[1]
  // 2. 分解參數成數組
  return args.split(",").reduce((result, arg) => {
    // 3. 沒有參數,返回空數組,而不是[""]
    let r = arg.replace(/\/\*.*\*\//, "").trim()
    r && result.push(r)
    return result
  }, [])
}

補充

filter 過濾假值

falsenull0""undefinedNaN

let ary = [0, 1, '', , NaN, 'a', null, false, [], {}]
/* 使用Boolean構造函數來進行一次轉換 */
const getRidOfFalse = ary => ary.filter(Boolean)
getRidOfFalse(ary)	// [1, "a", [], {}]

正則說明

字符 含義
(?<=y)x 匹配’x’,僅當’x’前面是’y’。這種叫做後行斷言

參考地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章