Zach_is_my_name Zach_is_my_name - 1 month ago 13
Javascript Question

Why does charAt not detect a string?

Why does the following function return a vowel at index 2 when, index 2 is NOT a vowel?

function isVowel(name) {
console.log("The third letter of " + name + " " + "is " + name.charAt(2))
if (name.charAt(2) === "a" || "i" || "o" || "u")
console.log("3rd letter is vowel")
else
console.log("3rd letter is NOT vowel")
}

isVowel("abcdefg")

/*Outputs:*/ The third letter of abcdefg is c
3rd letter is vowel

Answer

In JavaScript (and all the other languages with similar syntax), this line:

if (name.charAt(2) === "a" || "i" || "o" || "u")

means

  • if name.charAt(2) === "a"
  • or "i"
  • or "o"
  • or "u"

it does not mean

  • if name.charAt(2) === "a"
  • or name.charAt(2) === "i"
  • or name.charAt(2) === "o"
  • or name.charAt(2) === "u"

In a lot of languages you'd get an error because "i" isn't a boolean value, so || "i" is an odd thing to say; but JavaScript is happy to do type coercion, and so false || "e" results in true because "e" is a "truthy"1 value.

To make it mean what you want it to mean, you have to repeat the left-hand operand:

if (name.charAt(2) === "a" ||
    name.charAt(2) === "i" ||
    name.charAt(2) === "o" ||
    name.charAt(2) === "u")

You might want to use a variable to avoid repeatedly calling charAt, or look at doing something else, like this typical "is X in Y" approach:

if ("aiou".indexOf(name.charAt(2) !== -1)

Side note: Aren't you missing "e" (and sometimes "y")? ;-)


1 "truthy value" - Values that coerce to true when used as booleans are truthy; ones that coerce to false are "falsy." The falsy values are 0, "", NaN, null, undefined, and of course, false; all other values are truthy.