Search code examples
javascripttry-catch

Javascript Try-Catch Performance Vs. Error Checking Code


Would it be faster to just put code inside a try-catch block instead of performing various error checks?

For example..

function getProjectTask(projectTaskId) {
    if (YAHOO.lang.isUndefined(projectTaskId) || YAHOO.lang.isNull(projectTaskId) && !YAHOO.lang.isNumber(projectTaskId)) {
        return null;
    }

    var projectPhaseId, projectPhaseIndex, projectTaskIndex, projectPhases, projectPhase, projectTask;

    if (!YAHOO.lang.hasOwnProperty(projectTaskPhaseMap, projectTaskId)) {
        return null;
    }

    projectPhaseId = projectTaskPhaseMap[projectTaskId];

    if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhasesMap, projectPhaseId)) {
        return null;
    }

    projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId];
    if (YAHOO.lang.isUndefined(projectPhaseIndex) || YAHOO.lang.isNull(projectPhaseIndex) || !YAHOO.lang.hasOwnProperty(scheduleData.ProjectPhases[projectPhaseIndex])) {
        return null;
    }
    projectPhase = scheduleData.ProjectPhases[projectPhaseIndex];

    if (!YAHOO.lang.hasOwnProperty(projectPhase.ProjectTasksMap, projectTaskId)) {
        return null;
    }

    projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId];

    if (YAHOO.lang.isUndefined(projectTaskIndex) || YAHOO.lang.isNull(projectTaskIndex)) {
        return null;
    }

    projectTask = scheduleData.ProjectTasks[projectTaskIndex];
}

VS

function getProjectTask(projectTaskId) {
    try {
        projectPhaseId = projectTaskPhaseMap[projectTaskId];
        projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId];
        projectPhase = scheduleData.ProjectPhases[projectPhaseIndex];
        projectTaskIndex = projectPhase.ProjectTasksMap[projectTaskId];
        projectTask = scheduleData.ProjectTasks[projectTaskIndex];

    }
    catch (e) {
        return null;
    }
}

I hope my question makes sense. I would be happy to clarify. Thank you!


Solution

  • "Programs must be written for people to read, and only incidentally for machines to execute."

    Abelson & Sussman, SICP, preface to the first edition

    Always aim for readable code. The key thing to remember is:

    Avoid try-catch in performance-critical functions, and loops

    Anywhere else they won't do much harm. Use them wisely, use them when they make sense.

    But as I see you clearly misuse some functions for error checking. You can test for the desired objects and properties of objects right before you use them instead of complex checking. And:

    if (YAHOO.lang.isUndefined(projectPhaseId) || YAHOO.lang.isNull(projectPhaseId))
    

    can be written as

    if (projectPhaseId != null)
    

    for example... So the example above can be fairly readable even without try catches. You seem to misuse YUI a bit.

    I would bet this works as expected:

    function getProjectTask(projectTaskId) {
    
       var projectPhaseId    = projectTaskPhaseMap[projectTaskId],
           projectPhaseIndex = scheduleData.ProjectPhasesMap[projectPhaseId],
           projectPhase      = scheduleData.ProjectPhases[projectPhaseIndex];
    
      if (projectPhase == null) return null; // projectPhase would break the chain
    
      var projectTaskIndex  = projectPhase.ProjectTasksMap[projectTaskId],
          projectTask       = scheduleData.ProjectTasks[projectTaskIndex];
    
       return projectTask || null; // end of the dependency chain
    
    }
    

    How cool is that? :)