最佳实践:对象与开关

Best practices: object vs switch

   currentAlbum: string | undefined;
   video: any = { id: 'TYYW_WwYHuM' };

我正在尝试改进我的代码,其中我写了一个长而丑陋的开关,我想把它变成一个语法更好的对象。

但我想知道,为什么我把它写在它起作用的函数中:

takeVideo(currentAlbum: string | undefined): void {
 switch (this.currentAlbum) {
   case 'the red hot chili peppers':
    this.video.id = 'yOYmdyaSOCg';
    break;
   case 'Freaky Styley':
    this.video.id = '3Z4JUqA_bKE';
    break;
   case 'The Uplift Mofo Party Plan':
    this.video.id = 'a8DPkw5Nc64';
    break;
   case "Mother's Milk":
    this.video.id = 'HZySqMlEuSQ';
    break;
   case 'Blood Sugar Sex Magik':
    this.video.id = 'Mr_uHJPUlO8';
    break;
   case 'One Hot Minute':
    this.video.id = 'vV8IAOojoAA';
    break;
   case 'Californication':
    this.video.id = 'mzJj5-lubeM';
    break;
   case 'By the Way':
    this.video.id = 'JnfyjwChuNU';
    break;
   case 'Stadium Arcadium':
    this.video.id = 'oDNcL1VP3rY';
    break;
   case "I'm with You":
    this.video.id = 'qOgFHMEJMeY';
    break;
   case 'The Getaway':
    this.video.id = 'Q0oIoR9mLwc';
    break;
   default:
    this.video.id = 'TYYW_WwYHuM';
 }
}

但是如果我写这个,这应该是最佳实践,它行不通吗?

   takeVideo(currentAlbum: string | undefined): void {
     const videos = {
       'the red hot chili peppers': (this.video.id = 'yOYmdyaSOCg'),
       'Freaky Styley': (this.video.id = '3Z4JUqA_bKE'),
       'The Uplift Mofo Party Plan': (this.video.id = 'a8DPkw5Nc64'),
       "Mother's Milk": (this.video.id = 'HZySqMlEuSQ'),
       'Blood Sugar Sex Magik': (this.video.id = 'Mr_uHJPUlO8'),
       'One Hot Minute': (this.video.id = 'vV8IAOojoAA'),
       'Californication': (this.video.id = 'mzJj5-lubeM'),
       'By the Way': (this.video.id = 'JnfyjwChuNU'),
       'Stadium Arcadium': (this.video.id = 'oDNcL1VP3rY'),
       "I'm with You": (this.video.id = 'qOgFHMEJMeY'),
       'The Getaway': (this.video.id = 'Q0oIoR9mLwc'),
     };

     return videos[currentAlbum] ?? this.video.id;
   }

首先,使用对象而不是 switch 语句不是最佳实践。
这取决于你在哪里使用它。

其次,你应该使用带赋值的函数而不是赋值。 即

takeVideo(currentAlbum: string | undefined): void {
    const videos = {
        'the red hot chili peppers':  function() { this.video.id = 'yOYmdyaSOCg'; return this.video.id; },
        'Freaky Styley':              function() { this.video.id = '3Z4JUqA_bKE'; return this.video.id; },
        'The Uplift Mofo Party Plan': function() { this.video.id = 'a8DPkw5Nc64'; return this.video.id; },
        "Mother's Milk":              function() { this.video.id = 'HZySqMlEuSQ'; return this.video.id; },
        'Blood Sugar Sex Magik':      function() { this.video.id = 'Mr_uHJPUlO8'; return this.video.id; },
        'One Hot Minute':             function() { this.video.id = 'vV8IAOojoAA'; return this.video.id; },
        'Californication':            function() { this.video.id = 'mzJj5-lubeM'; return this.video.id; },
        'By the Way':                 function() { this.video.id = 'JnfyjwChuNU'; return this.video.id; },
        'Stadium Arcadium':           function() { this.video.id = 'oDNcL1VP3rY'; return this.video.id; },
        "I'm with You":               function() { this.video.id = 'qOgFHMEJMeY'; return this.video.id; },
        'The Getaway':                function() { this.video.id = 'Q0oIoR9mLwc'; return this.video.id; },
    };

    return videos[currentAlbum] ? videos[currentAlbum]() : this.video.id;
}

这是因为你的代码的赋值是所有在定义videos时执行的。

现在,我认为这段代码比您尝试做的要好得多

takeVideo(currentAlbum: string | undefined): void {
    const videos = {
        'the red hot chili peppers':  'yOYmdyaSOCg',
        'Freaky Styley':              '3Z4JUqA_bKE',
        'The Uplift Mofo Party Plan': 'a8DPkw5Nc64',
        "Mother's Milk":              'HZySqMlEuSQ',
        'Blood Sugar Sex Magik':      'Mr_uHJPUlO8',
        'One Hot Minute':             'vV8IAOojoAA',
        'Californication':            'mzJj5-lubeM',
        'By the Way':                 'JnfyjwChuNU',
        'Stadium Arcadium':           'oDNcL1VP3rY',
        "I'm with You":               'qOgFHMEJMeY',
        'The Getaway':                'Q0oIoR9mLwc',
    };

    this.video.id = videos[currentAlbum] ?? this.video.id;
    return this.video.id;
}

你想要的是这样的:

const VIDEOS = {
  'the red hot chili peppers': 'yOYmdyaSOCg',
  'Freaky Styley': '3Z4JUqA_bKE',
  ...
}

function takeVideo(currentAlbum: keyof typeof VIDEOS) {
  this.video.id = VIDEOS[currentAlbum];
}

还要注意 currentAlbum: keyof typeof VIDEOS 的类型——这使得即使调用 takeVideo 也会被检查类型,即

takeVideo('Freaky Styley'); // is valid
takeVideo('some unknown title'); // is invalid - type error