refactoring when two functions share some similarity

我与影子孤独终老i 提交于 2020-02-15 23:07:20

问题


I have two tabs in my app one is a player tab and another is a coaching tab. I have a function1 in the player tab and function2 in the coaching tab.

function1

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
})

function2

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
})

When I look at both the functions I see they are very similar, the only difference is that the player tab has parents and the coaching tab does not. I was wondering if the functions are fine as they are or if they should be refactored. Is it bad practice if I just leave them as they are? If I am to refactor I was not sure how I can make a function generic enough to accommodate the differences of two tabs. I would love thoughts and as I am new to JS please forgive me if I have misspoken.


回答1:


jQuery tends to fail silently if it doesn't find an element (because it doesn't exist in the document or because it's hidden at function runtime). If this is ok with you and you don't get errors, all good.

Otherwise, move some of that duplicated code out to a new named function and pass an argument to it, and use that to determine whether to act on those elements. Something like this:

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

// call the function
doCommonStuff(true);


来源:https://stackoverflow.com/questions/60082844/refactoring-when-two-functions-share-some-similarity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!