我經常使用物件來傳遞一組選項。
在 99.9% 的情況下,我希望這些物件只包含我使用的屬性的一個子集。如果存在意外的屬性,則幾乎總是意味著存在拼寫錯誤或邏輯錯誤。
有沒有一種簡單的方法可以確保選項物件不包含意外屬性?我只在測驗和除錯期間才真正需要這個,所以它不一定是高效的。
例子:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console} = opts
if (silent) return
for (let i=0; i<times; i ) {
logger.log( text )
}
}
// all good here
log( "Hello World!", {times:1} )
// "slient" is not a valid option. It's a typo.
// I want this call to throw an exception.
log( "Bye World!", {times:2, slient:true} )
我知道我可以通過一個接收預期屬性名稱的函式來實作它:
function testOpts( opts={}, optNames=[] ) { /* ... */ }
testOpts( opts, ["times", "silent", "logger"] )
但是保持這種方式很無聊且容易出錯:每次我更改一個選項時,我都需要更新這些引數。我嘗試過,但經常忘記更新它,所以我的函式不斷接受我洗掉的引數,這是我想避免的。
有沒有更好的解決方案讓我只寫一次屬性名稱?
uj5u.com熱心網友回復:
如果您只想撰寫它們一次,那么唯一的方法就是在log您使用它們的函式中。確實有一種方法可以做到這一點:在 destructuring 中使用rest 語法,并測驗除了預期的(解構)屬性之外沒有其他屬性:
function log( text, opts={} ) {
const {times=1, silent=false, logger=console, ...rest} = opts
// ^^^^^^^
assertEmpty(rest);
if (silent) return
for (let i=0; i<times; i ) {
logger.log( text )
}
}
function assertEmpty(val) {
const keys = Object.keys(val);
if (keys.length) {
throw new RangeError(`Unexpected properties ${keys.join(', ')} in object`);
}
}
除此之外,使用靜態分析工具如 TypeScript 或 Flow,他們很容易捕捉到這些錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/373224.html
標籤:javascript 目的 特性
上一篇:更改物件鍵和值并保留初始順序
下一篇:比較兩個不同類物件的整數值
