Reverse a String

String Reversal Techniques

Reversing a string is a common interview question and programming exercise. JavaScript provides multiple approaches to solve this problem.

Try Reversing Strings

Code Editor
Console Output
Click "Run" to execute your code...

Method 1: Built-in Methods (Easiest)

function reverseString1(str) {
  return str.split('').reverse().join('');
}

console.log(reverseString1('hello')); // 'olleh'
console.log(reverseString1('JavaScript')); // 'tpircSavaJ'
console.log(reverseString1('12345')); // '54321'

// Explanation:
// 1. split('') - converts string to array of characters
// 2. reverse() - reverses the array
// 3. join('') - converts array back to string

// Step by step:
const str = 'hello';
const arr = str.split('');      // ['h', 'e', 'l', 'l', 'o']
const reversed = arr.reverse(); // ['o', 'l', 'l', 'e', 'h']
const result = reversed.join(''); // 'olleh'

// One-liner with arrow function
const reverse = str => str.split('').reverse().join('');
console.log(reverse('world')); // 'dlrow'

Method 2: For Loop

function reverseString2(str) {
  let reversed = '';
  
  for (let i = str.length - 1; i >= 0; i--) {
    reversed += str[i];
  }
  
  return reversed;
}

console.log(reverseString2('hello')); // 'olleh'
console.log(reverseString2('JavaScript')); // 'tpircSavaJ'

// Alternative: Forward loop
function reverseString2b(str) {
  let reversed = '';
  
  for (let i = 0; i < str.length; i++) {
    reversed = str[i] + reversed; // Prepend each character
  }
  
  return reversed;
}

console.log(reverseString2b('world')); // 'dlrow'

// For...of loop
function reverseString2c(str) {
  let reversed = '';
  
  for (const char of str) {
    reversed = char + reversed;
  }
  
  return reversed;
}

console.log(reverseString2c('coding')); // 'gnidoc'

Method 3: Array Reduce

function reverseString3(str) {
  return str.split('').reduce((reversed, char) => {
    return char + reversed;
  }, '');
}

console.log(reverseString3('hello')); // 'olleh'

// More concise version
function reverseString3b(str) {
  return str.split('').reduce((rev, char) => char + rev, '');
}

console.log(reverseString3b('JavaScript')); // 'tpircSavaJ'

// With array spread
function reverseString3c(str) {
  return [...str].reduce((rev, char) => char + rev, '');
}

console.log(reverseString3c('world')); // 'dlrow'

// Explanation:
// reduce iterates through each character
// Each character is prepended to the accumulated string
// Initial value is empty string ''

Method 4: Recursion

function reverseString4(str) {
  // Base case: empty or single character
  if (str.length <= 1) {
    return str;
  }
  
  // Recursive case: last char + reverse of rest
  return str[str.length - 1] + reverseString4(str.slice(0, -1));
}

console.log(reverseString4('hello')); // 'olleh'

// Alternative recursive approach
function reverseString4b(str) {
  if (str === '') {
    return '';
  }
  
  return reverseString4b(str.slice(1)) + str[0];
}

console.log(reverseString4b('JavaScript')); // 'tpircSavaJ'

// Explanation (for 'abc'):
// reverseString4b('abc')
//   = reverseString4b('bc') + 'a'
//   = (reverseString4b('c') + 'b') + 'a'
//   = ((reverseString4b('') + 'c') + 'b') + 'a'
//   = (('' + 'c') + 'b') + 'a'
//   = 'cba'

// Tail recursion optimized
function reverseString4c(str, reversed = '') {
  if (str === '') {
    return reversed;
  }
  
  return reverseString4c(str.slice(1), str[0] + reversed);
}

console.log(reverseString4c('world')); // 'dlrow'

Method 5: Two Pointers / In-Place (Arrays)

// In-place reversal (works with arrays)
function reverseArray(arr) {
  let left = 0;
  let right = arr.length - 1;
  
  while (left < right) {
    // Swap elements
    [arr[left], arr[right]] = [arr[right], arr[left]];
    left++;
    right--;
  }
  
  return arr;
}

// For strings (convert to array first)
function reverseString5(str) {
  const arr = str.split('');
  let left = 0;
  let right = arr.length - 1;
  
  while (left < right) {
    [arr[left], arr[right]] = [arr[right], arr[left]];
    left++;
    right--;
  }
  
  return arr.join('');
}

console.log(reverseString5('hello')); // 'olleh'

// Without destructuring
function reverseString5b(str) {
  const arr = str.split('');
  let left = 0;
  let right = arr.length - 1;
  
  while (left < right) {
    const temp = arr[left];
    arr[left] = arr[right];
    arr[right] = temp;
    left++;
    right--;
  }
  
  return arr.join('');
}

console.log(reverseString5b('JavaScript')); // 'tpircSavaJ'

Bonus: Special Cases

// Reverse words in a sentence
function reverseWords(sentence) {
  return sentence.split(' ').reverse().join(' ');
}

console.log(reverseWords('Hello World JavaScript'));
// 'JavaScript World Hello'

// Reverse each word individually
function reverseEachWord(sentence) {
  return sentence
    .split(' ')
    .map(word => word.split('').reverse().join(''))
    .join(' ');
}

console.log(reverseEachWord('Hello World'));
// 'olleH dlroW'

// Reverse string but keep word order
function reverseStringKeepWords(sentence) {
  return sentence
    .split(' ')
    .map(word => word.split('').reverse().join(''))
    .join(' ');
}

// Palindrome check (using reverse)
function isPalindrome(str) {
  const cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, '');
  return cleaned === cleaned.split('').reverse().join('');
}

console.log(isPalindrome('A man a plan a canal Panama')); // true
console.log(isPalindrome('race a car')); // false
console.log(isPalindrome('Was it a car or a cat I saw')); // true

// Performance comparison
const longString = 'a'.repeat(100000);

console.time('Built-in methods');
reverseString1(longString);
console.timeEnd('Built-in methods');

console.time('For loop');
reverseString2(longString);
console.timeEnd('For loop');

console.time('Reduce');
reverseString3(longString);
console.timeEnd('Reduce');

// Result: For loop is usually fastest for very long strings
// Built-in methods are fastest for short-medium strings and most readable

Key Points

  • Built-in methods (split, reverse, join) are most readable
  • For loop provides better performance for very long strings
  • Recursion is elegant but can cause stack overflow with large strings
  • Two pointers approach is efficient for in-place reversal
  • Consider readability vs performance based on use case
  • strings are immutable in JavaScript
  • Each method has trade-offs in terms of code clarity and speed