The line to scrub punctuation and spaces could be simplified from:
str = str.replace(/[^\w\s]|_/g, "").toLowerCase().split(" ").join("");
str = str.replace(/[^\w]|_/g, "").toLowerCase();
Essentially, your original regex marks spaces as legal characters, which you're then going and later scrubbing out with
.split(" ").join(""). By excluding the
\s in your regex, you cause the regex to match spaces in the string, which would then be replaced along with the punctuation in the
str.replace method. See this regex101.
I'd also ask you to consider what it means to be a palindrome. Words like
racecar. The way you're currently doing it is by reversing the string, and then checking equality. I suggest it could be half (worst case) or O(1) (best case) the complexity if you'd think about how you could check the front and the back of the string at the same time. I won't give you the code how to do this, but I'll outline the algorithm. Consider the word
Urithiru, a faster way to check palindrome-ness would to be doing something like this:
Take the first and last letters, compare them, if true, then grab the next in sequence (next from the start; next from reverse). Essentially the program would evaluate it in these steps:
Urithiru and palindromes have the worst complexity cases for the algorithm because every letter must be checked to prove it's a palidrome. However, if you checked a work like
supercalifragilisticexpialidocious, it'd only take two iterations, and then most words in the English language (the ones that don't start and end with the same letters), would be an O(1) result. For instance,
English would fail after the first comparison.