使用对象字面量替代JavaScript的switch语句
JavaScript的switch
语句是我发现很难记住语法的几个事情之一(很高兴VS Code有自动补全)。从语法上讲,它也有些不太协调,因为它是唯一不使用花括号的语句,并且你需要记住在每个case
后面加上break
。此外,它的性能也不太好,因为它的控制流是过程式的。
幸运的是,JavaScript的对象字面量对于我能想到的大多数switch
语句用例来说是一个相当不错的替代方案。思路是为每个switch
语句中的case
定义一个键,然后可以使用传递给switch
语句的表达式直接访问其值。
let fruit = 'oranges';
switch (fruit) {
case 'apples':
console.log('Apples');
break;
case 'oranges':
console.log('Oranges');
break;
}
// 输出:'Oranges'
const logFruit = {
'apples': () => console.log('Apples'),
'oranges': () => console.log('Oranges')
};
logFruit[fruit](); // 输出:'Oranges'
虽然这种方式更易读且更简洁,但它也更快。然而,我们还没有解决一个问题:default
情况。为了处理它,我们只需添加一个'default'
键,并检查表达式的值是否存在于我们的对象中。
let fruit = 'strawberries';
switch (fruit) {
case 'apples':
console.log('Apples');
break;
case 'oranges':
console.log('Oranges');
break;
default:
console.log('Unknown fruit');
}
// 输出:'Unknown fruit'
```js
const logFruit = {
'apples': () => console.log('苹果'),
'oranges': () => console.log('橙子'),
'default': () => console.log('未知水果')
};
(logFruit[fruit] || logFruit['default'])(); // 输出:'未知水果'
最后,我们的对象字面量替代方案应该能够处理类似于没有break
语句时的情况。这只是简单地提取和重用对象字面量中的逻辑。
let fruit = 'oranges';
switch (fruit) {
case 'apples':
case 'oranges':
console.log('已知水果');
break;
default:
console.log('未知水果');
}
// 输出:'已知水果'
const knownFruit = () => console.log('已知水果');
const unknownFruit = () => console.log('未知水果');
const logFruit = {
'apples': knownFruit,
'oranges': knownFruit,
'default': unknownFruit
};
(logFruit[fruit] || logFruit['default'])(); // 输出:'已知水果'
最后,我们可以将这个逻辑通用化并提取到一个简单的可重用函数中。我们将为它提供查找对象和一个可选的默认情况名称(我们将默认为_default
以避免任何冲突)。这个函数将返回一个具有适当查找逻辑的函数,我们可以使用它来替换任何switch
语句。
const switchFn = (lookupObject, defaultCase = '_default') =>
expression => (lookupObject[expression] || lookupObject[defaultCase])();
const knownFruit = () => console.log('已知水果');
const unknownFruit = () => console.log('未知水果');
const logFruit = {
'apples': knownFruit,
'oranges': knownFruit,
'default': unknownFruit
};
const fruitSwitch = switchFn(logFruit, 'default');
fruitSwitch('apples'); // 输出:'已知水果'
fruitSwitch('pineapples'); // 输出:'未知水果'