What is the difference between these two functions involving typeof

119 Views Asked by At

My teacher in JavaScript gave me an assignment to master functions. I tried to solve the assignment which requires me to make the output like the second code:

function showDetails(name = "unknown", age = "unknown", booleanez = "unknown") {
  let name22ez,num22ez,bool22ez;

  typeof booleanez === 'boolean'
    ? (bool22ez = booleanez)
    : typeof booleanez === "number"
    ? (bool22ez = age)
    : (bool22ez = name);

  typeof name === "string"
    ? (name22ez = name)
    : typeof name === "number"
    ? (name22ez = age)
    : (name22ez = booleanez);

  typeof age === "number"
    ? (num22ez = age)
    : typeof age === "string"
    ? (num22ez = name)
    : (num22ez = booleanez);
  return `Hello ${name22ez}, Your Age Is ${num22ez}, You ${
    bool22ez === true ? bool22ez =`Are` : bool22ez = `Are Not`
  } Available For Hire`;
}

document.write(showDetails("Osama", 38, true));
document.write(`<hr>`);
document.write(showDetails(38, "Osama", true));
document.write(`<hr>`);
document.write(showDetails(true, 38, "Osama"));
document.write(`<hr>`);
document.write(showDetails(false, "Osama", 38));

The Output Was:

Hello Osama, Your Age Is 38, You Are Available For Hire
Hello Osama, Your Age Is 38, You Are Available For Hire
Hello Osama, Your Age Is 38, You Are Available For Hire
Hello 38, Your Age Is false, You Are Available For Hire 

I tried so many times, for like 4 hours, to fix it, but I didn't so, I took the answer from another student and his answer was this:

function checkStatus(a, b, c) {
    let str, num, bool;
    typeof a === "string"
        ? (str = a)
        : typeof b === "string"
        ? (str = b)
        : (str = c);
    typeof a === "number"
        ? (num = a)
        : typeof b === "number"
        ? (num = b)
        : (num = c);
    typeof a === "boolean"
        ? (bool = a)
        : typeof b === "boolean"
        ? (bool = b)
        : (bool = c);
    return `Hello ${str}, Your Age Is ${num}, You ${
        bool ? "Are" : "Are Not"
    } Available For Hire`;
}

document.write(checkStatus("Osama", 38, true));
document.write(checkStatus(38, "Osama", true));
document.write(checkStatus(true, 38, "Osama"));
document.write(checkStatus(false, "Osama", 38));

The output was correct:

Hello Osama, Your Age Is 38, You Are Available For Hire 
Hello Osama, Your Age Is 38, You Are Available For Hire 
Hello Osama, Your Age Is 38, You Are Available For Hire 
Hello Osama, Your Age Is 38, You Are Not Available For Hire

What's the difference between mine and my fellow's code?

4

There are 4 best solutions below

0
Barmar On BEST ANSWER

The original code checks the type of each parameter. The parameter whose type is string is used as the name, the parameter whose type is number is used as the age, and the parameter whose type is boolean is used as the availability for hire.

Your conditional logic is totally mystifying to me. The first test in each ternary is correct -- if booleanez is boolean then it should be used for bool22ez. But the rest make no sense. If booleanez is a number, why does that mean that the age parameter should be assigned to bool2ez?

You need to use the same logic as the original, testing each parameter for a particular type, then using that as the value to assign to the variable that requires that type.

  typeof booleanez === 'boolean'
    ? (bool22ez = booleanez)
    : typeof age === "boolean"
    ? (bool22ez = age)
    : (bool22ez = name);

And since you're assigning the same variable, you should use the ternary just in the value part of the assignment rather than repeating the variable to assign to.

bool22ez = 
    typeof booleanez === 'boolean'
        ? booleanez
        : typeof age === "boolean"
        ? age
        : name;
0
m-s7 On

To add to Barmar's answer, this is the correct code:

function showDetails(name = "unknown", age = "unknown", booleanez = "unknown") {
  let name22ez,num22ez,bool22ez;

  typeof name === "string"
    ? (name22ez = name)
    : typeof age === "string"
    ? (name22ez = age)
    : (name22ez = booleanez);
  typeof age === "number"
    ? (num22ez = age)
    : typeof name === "number"
    ? (num22ez = name)
    : (num22ez = booleanez);
  typeof booleanez === 'boolean'
    ? (bool22ez = booleanez)
    : typeof name === "boolean"
    ? (bool22ez = name)
    : (bool22ez = age);
  return `Hello ${name22ez}, Your Age Is ${num22ez}, You ${
    bool22ez === true ? bool22ez =`Are` : bool22ez = `Are Not`
  } Available For Hire`;
}
0
J. Titus On

Sorry to derail the comment section of your post. My point is, a more sensible way to write this function would be something along the lines of:

function showDetails(details) {
  // do some type checking up here for the existence of the values
  // because JavaScript is not a strongly typed language
  // ...
  // return the result if the details are provided
  return `Hello ${details.name}, Your Age Is ${details.age}, You ${details.forHire ? 'Are' : 'Are Not'} Available For Hire`;
}

console.log(showDetails({
  name: 'Osama',
  age: 38,
  forHire: true
}))

console.log(showDetails({
  name: 'Osama',
  age: 38,
  forHire: false
}))

Specifically for your assignment, though, listen to @Barmar.

0
Louys Patrice Bessette On

Even if I strongly agree with Barmar when he says It's completely stupid. Nobody in their right mind would write code like this., I just love those challenges.

Have a look at the solution I would suggest if I were you:

function showDetails(name = "unknown", age = "unknown", booleanez = "unknown") {
  
  // Accept specific types and one of each
  let acceptedTypes = ["string", "number", "boolean"];
  let typeSet = Array.from(new Set([typeof name, typeof age, typeof booleanez]));
  if (typeSet.length != 3) {
    return "ERROR - I need 3 different types of argument.";
  }
  for (let i = 0; i < typeSet.length; i++) {
    if (acceptedTypes.indexOf(typeSet[i]) == -1) {
      return "ERROR - At least one argument is not accepted.";
    }
  }
  
  // Beyond this point, proceed!
  let args = [
    { type: typeof name, value: name },
    { type: typeof age, value: age },
    { type: typeof booleanez, value: booleanez }
  ];

  // Expecting in this order: "string", "number", "boolean"
  // which are in the reversed alphabetical order...
  // So use sort b-a on the types ;)
  args.sort((a, b) => b.type.localeCompare(a.type))

  return `Hello ${args[0].value}, Your Age Is ${args[1].value}, You Are ${args[2].value ? `` : `Not `}Available For Hire`;
}

console.log(showDetails("Osama", 38, true));
console.log(showDetails(38, "Osama", true));
console.log(showDetails(true, 38, "Osama"));
console.log(showDetails(false, "Osama", 38));
console.log(showDetails(0, "Osama", 38));
console.log(showDetails(0, "Osama", { age: 38 }));
console.log(showDetails());