Search code examples
javascriptif-statementnestedswitch-statement

Evaluating if statements within switch expression


I've started using UglifyJS, and the way it nested some of the if statements within the switch expression was peculiar. I'm struggling to find any documentation on it. Neither Mozilla nor W3Schools say anything explicit about it. The script is running fine, I would just like to know more about how.

Global variable:

var today = new Date();

Original script:

function date(date = today) {
  if (date !== today) { date = new Date(date) };
  var year = date.getFullYear().toString(),
    month = (date.getMonth() + 1).toString(),
    day = date.getDate().toString(),
    shortDay,
    longDay;

  if (month.length === 1) { month = "0" + month };
  if (day.length === 1) { day = "0" + day };
  switch (date.getDay()) {
    case 0: shortDay = 'Sun'; longDay = "Sunday"; break;
    case 1: shortDay = 'Mon'; longDay = "Monday"; break;
    case 2: shortDay = 'Tue'; longDay = "Tuesday"; break;
    case 3: shortDay = 'Wed'; longDay = "Wednesday"; break;
    case 4: shortDay = 'Thu'; longDay = "Thursday"; break;
    case 5: shortDay = 'Fri'; longDay = "Friday"; break;
    case 6: shortDay = 'Sat'; longDay = "Saturday"; break;
  };

  return {
    full: year + '-' + month + '-' + day + ' ' + shortDay,
    mmddyyyy: month + '/' + day + '/' + year,
    mmddyy: month + '/' + day + '/' + year.substring(2),
    md: (date.getMonth() + 1).toString() + '/' + date.getDate().toString(),
    year, month, day, shortDay, longDay
  };
};

UglifyJS compressed script (reformatted for readability):

function date(date = today) {
  var shortDay, longDay,
    year = (date = date !== today ? new Date(date) : date).getFullYear().toString(),
    month = (date.getMonth() + 1).toString(),
    day = date.getDate().toString();

  switch (1 === month.length && (month = "0" + month), 1 === day.length && (day = "0" + day), date.getDay()) {
    case 0: shortDay = "Sun", longDay = "Sunday"; break;
    case 1: shortDay = "Mon", longDay = "Monday"; break;
    case 2: shortDay = "Tue", longDay = "Tuesday"; break;
    case 3: shortDay = "Wed", longDay = "Wednesday"; break;
    case 4: shortDay = "Thu", longDay = "Thursday"; break;
    case 5: shortDay = "Fri", longDay = "Friday"; break;
    case 6: shortDay = "Sat", longDay = "Saturday"
  }
  
  return {
    full: year + "-" + month + "-" + day + " " + shortDay,
    mmddyyyy: month + "/" + day + "/" + year,
    mmddyy: month + "/" + day + "/" + year.substring(2),
    md: (date.getMonth() + 1).toString() + "/" + date.getDate().toString(),
    year: year, month: month, day: day,
    shortDay: shortDay, longDay: longDay
  }
}

Solution

  • I believe that this is the part that is the most peculiar:

    switch (1 === month.length && (month = "0" + month), 1 === day.length && (day = "0" + day), date.getDay()) {
        case 0: shortDay = "Sun", longDay = "Sunday"; break;
        case 1: shortDay = "Mon", longDay = "Monday"; break;
        case 2: shortDay = "Tue", longDay = "Tuesday"; break;
        case 3: shortDay = "Wed", longDay = "Wednesday"; break;
        case 4: shortDay = "Thu", longDay = "Thursday"; break;
        case 5: shortDay = "Fri", longDay = "Friday"; break;
        case 6: shortDay = "Sat", longDay = "Saturday"
      }
    

    Comma operator

    First of all, there is a comma operator in JavaScript which always returns the last element. For example:

    const x = (1, 2, 3, 4, 5)
    console.log(x) // 5
    

    So this:

    switch (1 === month.length && (month = "0" + month), 1 === day.length && (day = "0" + day), date.getDay()) {
    

    Looks exactly like this:

    switch (date.getDay()) {
    

    From the switch's point of view.

    && operator

    Also, && operator stops if the left operand is falsy:

    false && console.log('something') // doesn't log anything
    true && console.log('something') // logs something
    

    So:

    // month is equal to '0' + month, but only if 1 === month.length
    1 === month.length && (month = "0" + month)
    // same here
    1 === day.length && (day = "0" + day)