'use strict'; // avoid ambiguity and sloppy errors /** * Tests wether or not a given string is a Palindrome * @param {string} stringToTest - the string to test. */ function isPalindrome(stringToTest) { var start = 0, end; // make sure we have a string. if (typeof stringToTest !== "string") { // throw if we didn't get a string throw new TypeError("isPalindrome() expected a string, but got " + Object.prototype.toString.call(stringToTest) + " instead!"); } // normalize string by lowercasing and removing non-word characters stringToTest = stringToTest .toLowerCase() .replace(/[^a-z0–9]/ig, ''); if (stringToTest.length === 0) { // warn if we have no valid characters to test console.log("No valid characters to test, treated as empty string" + "\nStack: \n" + new Error().stack); return true; // an empty string is a palindrome. } end = stringToTest.length - 1; // compare characters from outside in. stop when we get to the middle. while (start < end) { if (stringToTest[start] !== stringToTest[end]) { return false; } else { start++; end--; } } // if we get here, it's a palindrome return true; } // tests (should be in a seperate file using a test framework) console.log(isPalindrome("something that is not a palindrome") + " = false"); console.log(isPalindrome("something that is \n not a palindrome") + " = false"); console.log(isPalindrome("race \n car") + " = true"); console.log(isPalindrome("") + " = true + warn"); console.log(isPalindrome(" ") + " = true + warn"); console.log(isPalindrome("1221") + " = true"); console.log(isPalindrome("0") + " = true"); console.log(isPalindrome("racecar") + " = true"); console.log(isPalindrome("No 'x' in Nixon!") + " = true"); console.log(isPalindrome("~~!~!~") + " = true + warn"); console.log(isPalindrome("Momsie") + " = false"); console.log(isPalindrome(12)); // blow up console.log(isPalindrome(undefined)); // blow up console.log(isPalindrome(null)); // blow up