【问题标题】:refactoring when two functions share some similarity当两个函数有一些相似之处时进行重构
【发布时间】:2026-01-28 03:55:01
【问题描述】:

我的应用中有两个选项卡,一个是球员选项卡,另一个是教练选项卡。我在球员选项卡中有一个功能1,在教练选项卡中有一个功能2。

函数1

var beforeList = $('#players').val()
$('#players').change(function () {
  var afterList = $(this).val()
  var selectedPlayer = ''

  if (!beforeList) {
    selectedPlayer = afterList[0] 
    $('parent option[value=' + selectedPlayer + ']').add()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').add()
  } else if (!afterList) {
    selectedPlayer = beforeList[0] 
    $('parent option[value=' + selectedPlayer + ']').remove()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').remove()
  } else if (beforeList.length > afterList.length) {
    selectedPlayer = getselectedPlayer(beforeList, afterList) 
    $('parent option[value=' + selectedPlayer + ']').remove()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').remove()
  } else if (beforeList.length < afterList.length) {
    selectedPlayer = getselectedPlayer(afterList, beforeList) 
    $('parent option[value=' + selectedPlayer + ']').add()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').add()
  }

  if (afterList) {
    for (var i = 0; i < afterList.length; i++) {
      var optionInParentB = ($('#dad option[value=' + afterList[i] + ']').length > 0)
      var optionInParentA = ($('#mom option[value=' + afterList[i] + ']').length > 0)
      var optionInInjuredPlayer = ($('#injuredPlayer option[value=' + afterList[i] + ']').length > 0)
      if (!optionInParentB) {
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#dad')
      }
      if (!optionInParentA) {
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#mom')
      }
      if (!optionInInjuredPlayer){
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#injuredPlayer')
      }
    }
  } else {
    $('#mom').empty()
    $('#dad').empty()
    $('#injuredPlayer').empty()
  }

  beforeList = afterList
})

函数2

var beforeList = $('#coach').val()
$('#coach').change(function () {
  var afterList = $(this).val()
  var selectedCoach = ''

  if (!beforeList) {
    selectedCoach = afterList[0] 
    $('#injuredCoach option[value=' + selectedCoach + ']').add()
  } else if (!afterList) {
    selectedCoach = beforeList[0] 
    $('#injuredCoach option[value=' + selectedCoach + ']').remove()
  } else if (beforeList.length > afterList.length) {
    selectedCoach = getselectedCoach(beforeList, afterList) 
    $('#injuredCoach option[value=' + selectedCoach + ']').remove()
  } else if (beforeList.length < afterList.length) {
    selectedCoach = getselectedCoach(afterList, beforeList) 
    $('#injuredCoach option[value=' + selectedCoach + ']').add()
  }

  if (afterList) {
    for (var i = 0; i < afterList.length; i++) {
      var optionInInjuredCoach = ($('#injuredCoach option[value=' + afterList[i] + ']').length > 0)
      if (!optionInInjuredCoach){
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#injuredCoach')
      }
    }
  } else {
    $('#injuredCoach').empty()
  }

  beforeList = afterList
})

当我查看这两个功能时,我发现它们非常相似,唯一的区别是球员选项卡有父母,而教练选项卡没有。我想知道这些功能是否正常,或者是否应该重构它们。如果我让它们保持原样,这是不好的做法吗?如果要重构,我不确定如何使函数足够通用以适应两个选项卡的差异。我会喜欢想法,因为我是 JS 新手,如果我说错了,请原谅我。

【问题讨论】:

    标签: javascript jquery for-loop if-statement refactoring


    【解决方案1】:

    如果 jQuery 没有找到一个元素(因为它不存在于文档中或者因为它在函数运行时被隐藏),它往往会默默地失败。如果这对您来说没问题并且您没有收到错误,那么一切都很好。

    否则,将一些重复的代码移出到一个新的命名函数并传递一个参数给它,并使用它来确定是否对这些元素采取行动。像这样的:

    // define the function
    function doCommonStuff(doDad) {
        if (doDad) {
            // do Dad stuff
        }
    }
    
    // call the function
    doCommonStuff(true);
    

    【讨论】:

    • 嗯,我明白了,但不知道如何去掉共同点,因为有些事情是共同的,但同时又是不同的。就像在这两种情况下,我都在遍历列表,但在第一种情况下,我必须考虑父母,而在第二种情况下,我不需要
    最近更新 更多