How do you reverse a string in-place in JavaScript?

JavascriptStringReverse

Javascript Problem Overview


How do you reverse a string in-place in JavaScript when it is passed to a function with a return statement, without using built-in functions (.reverse(), .charAt() etc.)?

Javascript Solutions


Solution 1 - Javascript

As long as you're dealing with simple ASCII characters, and you're happy to use built-in functions, this will work:

function reverse(s){
    return s.split("").reverse().join("");
}

If you need a solution that supports UTF-16 or other multi-byte characters, be aware that this function will give invalid unicode strings, or valid strings that look funny. You might want to consider this answer instead.

[...s] is Unicode aware, a small edit gives:-

function reverse(s){
    return [...s].reverse().join("");
}

Solution 2 - Javascript

The following technique (or similar) is commonly used to reverse a string in JavaScript:

// Don’t use this!
var naiveReverse = function(string) {
	return string.split('').reverse().join('');
}

In fact, all the answers posted so far are a variation of this pattern. However, there are some problems with this solution. For example:

naiveReverse('foo 𝌆 bar');
// → 'rab �� oof'
// Where did the `𝌆` symbol go? Whoops!

If you’re wondering why this happens, read up on JavaScript’s internal character encoding. (TL;DR: 𝌆 is an astral symbol, and JavaScript exposes it as two separate code units.)

But there’s more:

// To see which symbols are being used here, check:
// http://mothereff.in/js-escapes#1ma%C3%B1ana%20man%CC%83ana
naiveReverse('mañana mañana');
// → 'anãnam anañam'
// Wait, so now the tilde is applied to the `a` instead of the `n`? WAT.

A good string to test string reverse implementations is the following:

'foo 𝌆 bar mañana mañana'

Why? Because it contains an astral symbol (𝌆) (which are represented by surrogate pairs in JavaScript) and a combining mark (the in the last mañana actually consists of two symbols: U+006E LATIN SMALL LETTER N and U+0303 COMBINING TILDE).

The order in which surrogate pairs appear cannot be reversed, else the astral symbol won’t show up anymore in the ‘reversed’ string. That’s why you saw those �� marks in the output for the previous example.

Combining marks always get applied to the previous symbol, so you have to treat both the main symbol (U+006E LATIN SMALL LETTER N) as the combining mark (U+0303 COMBINING TILDE) as a whole. Reversing their order will cause the combining mark to be paired with another symbol in the string. That’s why the example output had instead of ñ.

Hopefully, this explains why all the answers posted so far are wrong.


To answer your initial question — how to [properly] reverse a string in JavaScript —, I’ve written a small JavaScript library that is capable of Unicode-aware string reversal. It doesn’t have any of the issues I just mentioned. The library is called Esrever; its code is on GitHub, and it works in pretty much any JavaScript environment. It comes with a shell utility/binary, so you can easily reverse strings from your terminal if you want.

var input = 'foo 𝌆 bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab 𝌆 oof'

As for the “in-place” part, see the other answers.

Solution 3 - Javascript

String.prototype.reverse_string=function() {return this.split("").reverse().join("");}

or

String.prototype.reverse_string = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

Solution 4 - Javascript

Detailed analysis and ten different ways to reverse a string and their performance details.

http://eddmann.com/posts/ten-ways-to-reverse-a-string-in-javascript/

Perfomance of these implementations:

Best performing implementation(s) per browser

  • Chrome 15 - Implemations 1 and 6
  • Firefox 7 - Implementation 6
  • IE 9 - Implementation 4
  • Opera 12 - Implementation 9

Here are those implementations:

Implementation 1:

function reverse(s) {
  var o = '';
  for (var i = s.length - 1; i >= 0; i--)
    o += s[i];
  return o;
}

Implementation 2:

function reverse(s) {
  var o = [];
  for (var i = s.length - 1, j = 0; i >= 0; i--, j++)
    o[j] = s[i];
  return o.join('');
}

Implementation 3:

function reverse(s) {
  var o = [];
  for (var i = 0, len = s.length; i <= len; i++)
    o.push(s.charAt(len - i));
  return o.join('');
}

Implementation 4:

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

Implementation 5:

function reverse(s) {
  var i = s.length,
      o = '';
  while (i > 0) {
    o += s.substring(i - 1, i);
    i--;
  }
  return o;
}

Implementation 6:

function reverse(s) {
  for (var i = s.length - 1, o = ''; i >= 0; o += s[i--]) { }
  return o;
}

Implementation 7:

function reverse(s) {
  return (s === '') ? '' : reverse(s.substr(1)) + s.charAt(0);
}

Implementation 8:

function reverse(s) {
  function rev(s, len, o) {
    return (len === 0) ? o : rev(s, --len, (o += s[len]));
  };
  return rev(s, s.length, '');
}

Implementation 9:

function reverse(s) {
  s = s.split('');
  var len = s.length,
      halfIndex = Math.floor(len / 2) - 1,
      tmp;
 

     for (var i = 0; i <= halfIndex; i++) {
        tmp = s[len - i - 1];
        s[len - i - 1] = s[i];
        s[i] = tmp;
      }
      return s.join('');
    }

Implementation 10

function reverse(s) {
  if (s.length < 2)
    return s;
  var halfIndex = Math.ceil(s.length / 2);
  return reverse(s.substr(halfIndex)) +
         reverse(s.substr(0, halfIndex));
}

Implementation 11

var reverser  = function(str){
let string = str.split('');

    for(i=0;i<string.length;i++){
        debugger;
        string.splice(i,0,string.pop());
    
    } 
    console.log(string.join())
}
reverser('abcdef')

Solution 5 - Javascript

The whole "reverse a string in place" is an antiquated interview question C programmers, and people who were interviewed by them (for revenge, maybe?), will ask. Unfortunately, it's the "In Place" part that no longer works because strings in pretty much any managed language (JS, C#, etc) uses immutable strings, thus defeating the whole idea of moving a string without allocating any new memory.

While the solutions above do indeed reverse a string, they do not do it without allocating more memory, and thus do not satisfy the conditions. You need to have direct access to the string as allocated, and be able to manipulate its original memory location to be able to reverse it in place.

Personally, i really hate these kinds of interview questions, but sadly, i'm sure we'll keep seeing them for years to come.

Solution 6 - Javascript

First, use Array.from() to turn a string into an array, then Array.prototype.reverse() to reverse the array, and then Array.prototype.join() to make it back a string.

const reverse = str => Array.from(str).reverse().join('');

Solution 7 - Javascript

In ECMAScript 6, you can reverse a string even faster without using .split('') split method, with the spread operator like so:

var str = [...'racecar'].reverse().join('');

Solution 8 - Javascript

Seems like I'm 3 years late to the party...

Unfortunately you can't as has been pointed out. See https://stackoverflow.com/questions/51185/are-javascript-strings-immutable-do-i-need-a-string-builder-in-js

The next best thing you can do is to create a "view" or "wrapper", which takes a string and reimplements whatever parts of the string API you are using, but pretending the string is reversed. For example:

var identity = function(x){return x};

function LazyString(s) {
    this.original = s;

    this.length = s.length;
    this.start = 0; this.stop = this.length; this.dir = 1; // "virtual" slicing
    // (dir=-1 if reversed)

    this._caseTransform = identity;
}

// syntactic sugar to create new object:
function S(s) {
    return new LazyString(s);
}

//We now implement a `"...".reversed` which toggles a flag which will change our math:

(function(){ // begin anonymous scope
    var x = LazyString.prototype;

    // Addition to the String API
    x.reversed = function() {
        var s = new LazyString(this.original);

        s.start = this.stop - this.dir;
        s.stop = this.start - this.dir;
        s.dir = -1*this.dir;
        s.length = this.length;

        s._caseTransform = this._caseTransform;
        return s;
    }

//We also override string coercion for some extra versatility (not really necessary):

    // OVERRIDE STRING COERCION
    //   - for string concatenation e.g. "abc"+reversed("abc")
    x.toString = function() {
        if (typeof this._realized == 'undefined') {  // cached, to avoid recalculation
            this._realized = this.dir==1 ?
                this.original.slice(this.start,this.stop) : 
                this.original.slice(this.stop+1,this.start+1).split("").reverse().join("");
            
            this._realized = this._caseTransform.call(this._realized, this._realized);
        }
        return this._realized;
    }

//Now we reimplement the String API by doing some math:

    // String API:
    
    // Do some math to figure out which character we really want
    
    x.charAt = function(i) {
        return this.slice(i, i+1).toString();
    }
    x.charCodeAt = function(i) {
        return this.slice(i, i+1).toString().charCodeAt(0);
    }
    
// Slicing functions:

    x.slice = function(start,stop) {
        // lazy chaining version of https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/slice

        if (stop===undefined)
            stop = this.length;

        var relativeStart = start<0 ? this.length+start : start;
        var relativeStop = stop<0 ? this.length+stop : stop;

        if (relativeStart >= this.length)
            relativeStart = this.length;
        if (relativeStart < 0)
            relativeStart = 0;

        if (relativeStop > this.length)
            relativeStop = this.length;
        if (relativeStop < 0)
            relativeStop = 0;

        if (relativeStop < relativeStart)
            relativeStop = relativeStart;

        var s = new LazyString(this.original);
        s.length = relativeStop - relativeStart;
        s.start = this.start + this.dir*relativeStart;
        s.stop = s.start + this.dir*s.length;
        s.dir = this.dir;

        //console.log([this.start,this.stop,this.dir,this.length], [s.start,s.stop,s.dir,s.length])
        
        s._caseTransform = this._caseTransform;
        return s;
    }
    x.substring = function() {
        // ...
    }
    x.substr = function() {
        // ...
    }

//Miscellaneous functions:

    // Iterative search
    
    x.indexOf = function(value) {
        for(var i=0; i<this.length; i++)
            if (value==this.charAt(i))
                return i;
        return -1;
    }
    x.lastIndexOf = function() {
        for(var i=this.length-1; i>=0; i--)
            if (value==this.charAt(i))
                return i;
        return -1;
    }

    // The following functions are too complicated to reimplement easily.
    // Instead just realize the slice and do it the usual non-in-place way.

    x.match = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.replace = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.search = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }
    x.split = function() {
        var s = this.toString();
        return s.apply(s, arguments);
    }

// Case transforms:

    x.toLowerCase = function() {
        var s = new LazyString(this.original);
        s._caseTransform = ''.toLowerCase;

        s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;

        return s;
    }
    x.toUpperCase = function() {
        var s = new LazyString(this.original);
        s._caseTransform = ''.toUpperCase;

        s.start=this.start; s.stop=this.stop; s.dir=this.dir; s.length=this.length;

        return s;
    }

})() // end anonymous scope

Demo:

> r = S('abcABC')
LazyString
  original: "abcABC"
  __proto__: LazyString

> r.charAt(1);       // doesn't reverse string!!! (good if very long)
"B"

> r.toLowerCase()    // must reverse string, so does so
"cbacba"

> r.toUpperCase()    // string already reversed: no extra work
"CBACBA"

> r + '-demo-' + r   // natural coercion, string already reversed: no extra work
"CBAcba-demo-CBAcba"

The kicker -- the following is done in-place by pure math, visiting each character only once, and only if necessary:

> 'demo: ' + S('0123456789abcdef').slice(3).reversed().slice(1,-1).toUpperCase()
"demo: EDCBA987654"

> S('0123456789ABCDEF').slice(3).reversed().slice(1,-1).toLowerCase().charAt(3)
"b"

This yields significant savings if applied to a very large string, if you are only taking a relatively small slice thereof.

Whether this is worth it (over reversing-as-a-copy like in most programming languages) highly depends on your use case and how efficiently you reimplement the string API. For example if all you want is to do string index manipulation, or take small slices or substrs, this will save you space and time. If you're planning on printing large reversed slices or substrings however, the savings may be small indeed, even worse than having done a full copy. Your "reversed" string will also not have the type string, though you might be able to fake this with prototyping.

The above demo implementation creates a new object of type ReversedString. It is prototyped, and therefore fairly efficient, with almost minimal work and minimal space overhead (prototype definitions are shared). It is a lazy implementation involving deferred slicing. Whenever you perform a function like .slice or .reversed, it will perform index mathematics. Finally when you extract data (by implicitly calling .toString() or .charCodeAt(...) or something), it will apply those in a "smart" manner, touching the least data possible.

Note: the above string API is an example, and may not be implemented perfectly. You also can use just 1-2 functions which you need.

Solution 9 - Javascript

There are many ways you can reverse a string in JavaScript. I'm jotting down three ways I prefer.

Approach 1: Using reverse function:

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

Approach 2: Looping through characters:

function reverse(str) {
  let reversed = '';

  for (let character of str) {
    reversed = character + reversed;
  }

  return reversed;
}

Approach 3: Using reduce function:

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

I hope this helps :)

Solution 10 - Javascript

Legible way using spread syntax:

const reverseString = str => [...str].reverse().join('');

console.log(reverseString('ABC'));

Solution 11 - Javascript

There are Multiple ways of doing it, you may check the following,

1. Traditional for loop(incrementing):

function reverseString(str){
        let stringRev ="";
        for(let i= 0; i<str.length; i++){
            stringRev = str[i]+stringRev;
        }
        return stringRev;
}
alert(reverseString("Hello World!"));

2. Traditional for loop(decrementing):

function reverseString(str){
    let revstr = "";
    for(let i = str.length-1; i>=0; i--){
        revstr = revstr+ str[i];
    }
    return revstr;
}
alert(reverseString("Hello World!"));

3. Using for-of loop

function reverseString(str){
    let strn ="";
    for(let char of str){
        strn = char + strn;
    }
    return strn;
}
alert(reverseString("Get well soon"));

4. Using the forEach/ high order array method:

function reverseString(str){

  let revSrring = "";
  str.split("").forEach(function(char){
    
    revSrring = char + revSrring;
  
  });
  return revSrring;
}
alert(reverseString("Learning JavaScript"));

5. ES6 standard:

function reverseString(str){

  let revSrring = "";
  str.split("").forEach(char => revSrring = char + revSrring);
  return revSrring;
}
alert(reverseString("Learning JavaScript"));

6. The latest way:

function reverseString(str){

  return str.split("").reduce(function(revString, char){
       return char + revString;
  }, "");
 
}

alert(reverseString("Learning JavaScript"));

7. You may also get the result using the following,

function reverseString(str){

  return str.split("").reduce((revString, char)=> char + revString, "");
 
}
alert(reverseString("Learning JavaScript"));

Solution 12 - Javascript

During an interview, I was asked to reverse a string without using any variables or native methods. This is my favorite implementation:

function reverseString(str) {
    return str === '' ? '' : reverseString(str.slice(1)) + str[0];
}

Solution 13 - Javascript

In ES6, you have one more option

function reverseString (str) {
  return [...str].reverse().join('')
}

reverseString('Hello');

Solution 14 - Javascript

This is the easiest way I think

var reverse = function(str) {
    var arr = [];
    
    for (var i = 0, len = str.length; i <= len; i++) {
        arr.push(str.charAt(len - i))
    }

    return arr.join('');
}

console.log(reverse('I want a 🍺'));

Solution 15 - Javascript

var str = 'sample string';
[].map.call(str, function(x) {
  return x;
}).reverse().join('');

OR

var str = 'sample string';
console.log(str.split('').reverse().join(''));

// Output: 'gnirts elpmas'

Solution 16 - Javascript

If you don't want to use any built in function. Try this

var string = 'abcdefg';
var newstring = '';

for(let i = 0; i < string.length; i++){
	newstring = string[i] += newstring;
}

console.log(newstring);

Solution 17 - Javascript

I know that this is an old question that has been well answered, but for my own amusement I wrote the following reverse function and thought I would share it in case it was useful for anyone else. It handles both surrogate pairs and combining marks:

function StringReverse (str)
{
  var charArray = [];
  for (var i = 0; i < str.length; i++)
    {
      if (i+1 < str.length)
        {
          var value = str.charCodeAt(i);
          var nextValue = str.charCodeAt(i+1);
          if (   (   value >= 0xD800 && value <= 0xDBFF
                  && (nextValue & 0xFC00) == 0xDC00) // Surrogate pair)
              || (nextValue >= 0x0300 && nextValue <= 0x036F)) // Combining marks
            {
              charArray.unshift(str.substring(i, i+2));
              i++; // Skip the other half
              continue;
            }
        }

      // Otherwise we just have a rogue surrogate marker or a plain old character.
      charArray.unshift(str[i]);
    }

  return charArray.join('');
}

All props to Mathias, Punycode, and various other references for schooling me on the complexities of character encoding in JavaScript.

Solution 18 - Javascript

You can't because JS strings are immutable. Short non-in-place solution

[...str].reverse().join``

let str = "Hello World!";
let r = [...str].reverse().join``;
console.log(r);

Solution 19 - Javascript

One new option is to use Intl.Segmenter which allows you to split on the visual graphemes (ie: user-perceived character units such as emojis, characters, etc.). Intl.Segmenter is currently a stage 4 proposal and there is a polyfill available for it if you wish to use it. It is also currently supported in the latest version of Chrome.

Here is how the reverse() method may look if you use Intl.Segmenter:

const reverse = str => {
  const segmenter = new Intl.Segmenter("en", {granularity: 'grapheme'});
  const segitr = segmenter.segment(str);
  const segarr = Array.from(segitr, ({segment}) => segment).reverse();
  return segarr.join('');
}

console.log(reverse('foo 𝌆 bar mañana mañana')); // anañam anañam rab 𝌆 oof
console.log(reverse('This 😊 emoji is happy')); // yppah si ijome 😊 sihT
console.log(reverse('Text surrogate pair 𝌆 composite pair möo varient selector ❤️ & ZWJ 👨‍👩‍👦')); // 👨‍👩‍👦 JWZ & ❤️ rotceles tneirav oöm riap etisopmoc 𝌆 riap etagorrus txeT

The above creates a segmenter to segment/split strings by their visual graphemes. Calling .segment() on the segmenter with the string input then returns an iterator, which produces objects of the form {segment, index, input, isWordLike}. The segment key from this object contains the string segment (ie: the individual grapheme). To convert the iterator to an array, we use Array.from() on the iterator and extract the segmented graphemes, which can be reversed with .reverse(). Lastly, we join the array back into a string using .join()


There is also another option which you can try that has better browser support than Intl.Segmenter, however isn't as bullet-proof:

const reverse = str => Array.from(str.normalize('NFC')).reverse().join('');

this helps deal with characters consisting of multiple code points and code units. As pointed out in other answers, there are issues with maintaining composite and surrogate pair ordering in strings such as 'foo 𝌆 bar mañana mañana'. Here 𝌆 is a surrogate pair consisting of two code units, and the last is a composite pair consisting of two Unicode characters to make up one grapheme (n+̃ = ).

In order to reverse each character, you can use the .reverse() method which is part of the Array prototype. As .reverse() is used on an array, the first thing to do is to turn the string into an array of characters. Typically, .split('') is used for this task, however, this splits up surrogate pairs which are made from up of multiple code units (as already shown in previous answers):

>> '𝌆'.split('')
>> `["�", "�"]`

Instead, if you invoke the String.prototype's Symbol.iterator method then you'll be able to retain your surrogate pairs within your array, as this iterates over the code points rather than the code units of your string:

>> [...'𝌆']
>> ["𝌆"]

The next thing to handle is any composite characters within the string. Characters that consist of two or more code points will still be split when iterated on:

>> [...'ö']   
>> ["o", "̈"]

The above separates the base character (o) from the diaresis, which is not desired behavior. This is because is a decomposed version of the character, consisting of multiple code points. To deal with this, you can use a string method introduced in ES6 known as String.prototype.normalize(). This method can compose multiple code points into its composed canonical form by using "NFC" as an argument. This allows us to convert the decomposed character (o + combining diaeresis) into its precomposed form ö (latin small letter o with diaeresis) which consists of only one code point. Calling .normalize() with "NFC" thus tries to replace multiple code points with single code points where possible. This allows graphemes consisting of two code points to be represented with one code point.

>> [...'ö'.normalize('NFC')]   
>> ["ö"]

As normalize('NFC') produces one character, it can then be reversed safely when amongst others. Putting both the spread syntax and normalization together, you can successfully reverse strings of characters such as:

const reverse = str => Array.from(str.normalize('NFC')).reverse().join('');

console.log(reverse('foo 𝌆 bar mañana mañana'));
console.log(reverse('This 😊 emoji is happy'));

There are a few cases where the above normalization+iteration will fail. For instance, the character ❤️ (heavy black heart ❤️) consists of two code points. The first being the heart and the latter being the variation selector-16 (U+FE0F) which is used to define a glyph variant for the preceding character. Other characters can also produce similar issues like this.

Another thing to look out for is ZWJ (Zero-width joiner) characters, which you can find in some scripts, including emoji. For example the emoji ‍‍ comprises of the Man, Woman and Boy emoji, each separated by a ZWJ. The above normalization + iteration method will not account for this either.

As a result, using Intl.Segmenter is the better choice over these two approaches. Currently, Chrome also has its own specific segmentation API known as Intl.v8BreakIterator. This segmentation API is nonstandard and something that Chrome simply just implements. So, it is subject to change and doesn't work on most browsers, so it's not recommended to use. However, if you're curious, this is how it could be done:

const reverse = str => {
  const iterator = Intl.v8BreakIterator(['en'], {type: 'character'});
  iterator.adoptText(str);
  const arr = [];
  let pos = iterator.first();
  while (pos !== -1) {
    const current = iterator.current();
    const nextPos = iterator.next();
    if (nextPos === -1) break;
    const slice = str.slice(current, nextPos);
    arr.unshift(slice);
  }
  return arr.join("");
}

console.log(reverse('foo 𝌆 bar mañana mañana')); // anañam anañam rab 𝌆 oof
console.log(reverse('This 😊 emoji is happy')); // yppah si ijome 😊 sihT
console.log(reverse('Text surrogate pair 𝌆 composite pair möo varient selector ❤️ & ZWJ 👨‍👩‍👦')); // 👨‍👩‍👦 JWZ & ❤️ rotceles tneirav oöm riap etisopmoc 𝌆 riap etagorrus txeT

Solution 20 - Javascript

You can't reverse a string in place but you can use this:

String.prototype.reverse = function() {
    return this.split("").reverse().join("");
}

var s = "ABCD";
s = s.reverse();
console.log(s);

Solution 21 - Javascript

UTF-8 strings can have:

  • Combining diacritics such as which composed of the b character and a following ~ diacritic generated by the unicode escape sequnce \u0303;
  • Multi-byte characters such as 🎥; which is generated by the multi-byte unicode escape sequence \uD83C\uDFA5; and
  • Multiple characters may be combined together with a zero-width joiner character (given by the unicode escape sequence \u200D). For example, the character 👨‍👩‍👦 can be composed using the individual (multi-byte) emojis  then a zero-width joiner then  then another zero-width joiner then  such that the entire 3-person character is 8-bytes (\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66).

This will handle reversing all 3 cases and keeping the bytes in the correct order such that the characters are reversed (rather than naively reversing the bytes of the string):

(function(){
  var isCombiningDiacritic = function( code )
  {
    return (0x0300 <= code && code <= 0x036F)  // Comb. Diacritical Marks
        || (0x1AB0 <= code && code <= 0x1AFF)  // Comb. Diacritical Marks Extended
        || (0x1DC0 <= code && code <= 0x1DFF)  // Comb. Diacritical Marks Supplement
        || (0x20D0 <= code && code <= 0x20FF)  // Comb. Diacritical Marks for Symbols
        || (0xFE20 <= code && code <= 0xFE2F); // Comb. Half Marks

  };

  String.prototype.reverse = function()
  {
    let output = "";

    for ( let i = this.length; i > 0; )
    {
      let width = 0;
      let has_zero_width_joiner = false;

      while( i > 0 && isCombiningDiacritic( this.charCodeAt(i-1) ) )
      {
        --i;
        width++;
      }

      do {
        --i;
        width++;

        if (
             i > 0
          && "\uDC00" <= this[i]   && this[i]   <= "\uDFFF"
          && "\uD800" <= this[i-1] && this[i-1] <= "\uDBFF"
        )
        {
          --i;
          width++;
        }
        has_zero_width_joiner = i > 0 && "\u200D" == this[i-1];
        if ( has_zero_width_joiner )
        {
          --i;
          width++;
        }
      }
      while( i > 0 && has_zero_width_joiner );

      output += this.substr( i, width );
    }

    return output;
  }
})();

// Tests
[
  'abcdefg',
  'ab\u0303c',
  'a\uD83C\uDFA5b',
  'a\uD83C\uDFA5b\uD83C\uDFA6c',
  'a\uD83C\uDFA5b\u0306c\uD83C\uDFA6d',
  'TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡', // copied from http://stackoverflow.com/a/1732454/1509264
  'What 👨‍👩‍👦 is this?'
].forEach(
  function(str){ console.log( str + " -> " + str.reverse() ); }
);

Update

The above code identifies some of the more commonly used combining diacritics. A more complete list of combining diacritics (that could be swapped into the above code) is:

var isCombiningDiacritic = function( code )
{
  return (0x0300 <= code && code <= 0x036F)
      || (0x0483 <= code && code <= 0x0489)
      || (0x0591 <= code && code <= 0x05BD)
      || (code == 0x05BF)
      || (0x05C1 <= code && code <= 0x05C2)
      || (0x05C4 <= code && code <= 0x05C5)
      || (code == 0x05C7)
      || (0x0610 <= code && code <= 0x061A)
      || (0x064B <= code && code <= 0x065F)
      || (code == 0x0670)
      || (0x06D6 <= code && code <= 0x06DC)
      || (0x06DF <= code && code <= 0x06E4)
      || (0x06E7 <= code && code <= 0x06E8)
      || (0x06EA <= code && code <= 0x06ED)
      || (code == 0x0711)
      || (0x0730 <= code && code <= 0x074A)
      || (0x07A6 <= code && code <= 0x07B0)
      || (0x07EB <= code && code <= 0x07F3)
      || (code == 0x07FD)
      || (0x0816 <= code && code <= 0x0819)
      || (0x081B <= code && code <= 0x0823)
      || (0x0825 <= code && code <= 0x0827)
      || (0x0829 <= code && code <= 0x082D)
      || (0x0859 <= code && code <= 0x085B)
      || (0x08D3 <= code && code <= 0x08E1)
      || (0x08E3 <= code && code <= 0x0902)
      || (code == 0x093A)
      || (code == 0x093C)
      || (0x0941 <= code && code <= 0x0948)
      || (code == 0x094D)
      || (0x0951 <= code && code <= 0x0957)
      || (0x0962 <= code && code <= 0x0963)
      || (code == 0x0981)
      || (code == 0x09BC)
      || (0x09C1 <= code && code <= 0x09C4)
      || (code == 0x09CD)
      || (0x09E2 <= code && code <= 0x09E3)
      || (0x09FE <= code && code <= 0x0A02)
      || (code == 0x0A3C)
      || (0x0A41 <= code && code <= 0x0A51)
      || (0x0A70 <= code && code <= 0x0A71)
      || (code == 0x0A75)
      || (0x0A81 <= code && code <= 0x0A82)
      || (code == 0x0ABC)
      || (0x0AC1 <= code && code <= 0x0AC8)
      || (code == 0x0ACD)
      || (0x0AE2 <= code && code <= 0x0AE3)
      || (0x0AFA <= code && code <= 0x0B01)
      || (code == 0x0B3C)
      || (code == 0x0B3F)
      || (0x0B41 <= code && code <= 0x0B44)
      || (0x0B4D <= code && code <= 0x0B56)
      || (0x0B62 <= code && code <= 0x0B63)
      || (code == 0x0B82)
      || (code == 0x0BC0)
      || (code == 0x0BCD)
      || (code == 0x0C00)
      || (code == 0x0C04)
      || (0x0C3E <= code && code <= 0x0C40)
      || (0x0C46 <= code && code <= 0x0C56)
      || (0x0C62 <= code && code <= 0x0C63)
      || (code == 0x0C81)
      || (code == 0x0CBC)
      || (0x0CCC <= code && code <= 0x0CCD)
      || (0x0CE2 <= code && code <= 0x0CE3)
      || (0x0D00 <= code && code <= 0x0D01)
      || (0x0D3B <= code && code <= 0x0D3C)
      || (0x0D41 <= code && code <= 0x0D44)
      || (code == 0x0D4D)
      || (0x0D62 <= code && code <= 0x0D63)
      || (code == 0x0DCA)
      || (0x0DD2 <= code && code <= 0x0DD6)
      || (code == 0x0E31)
      || (0x0E34 <= code && code <= 0x0E3A)
      || (0x0E47 <= code && code <= 0x0E4E)
      || (code == 0x0EB1)
      || (0x0EB4 <= code && code <= 0x0EBC)
      || (0x0EC8 <= code && code <= 0x0ECD)
      || (0x0F18 <= code && code <= 0x0F19)
      || (code == 0x0F35)
      || (code == 0x0F37)
      || (code == 0x0F39)
      || (0x0F71 <= code && code <= 0x0F7E)
      || (0x0F80 <= code && code <= 0x0F84)
      || (0x0F86 <= code && code <= 0x0F87)
      || (0x0F8D <= code && code <= 0x0FBC)
      || (code == 0x0FC6)
      || (0x102D <= code && code <= 0x1030)
      || (0x1032 <= code && code <= 0x1037)
      || (0x1039 <= code && code <= 0x103A)
      || (0x103D <= code && code <= 0x103E)
      || (0x1058 <= code && code <= 0x1059)
      || (0x105E <= code && code <= 0x1060)
      || (0x1071 <= code && code <= 0x1074)
      || (code == 0x1082)
      || (0x1085 <= code && code <= 0x1086)
      || (code == 0x108D)
      || (code == 0x109D)
      || (0x135D <= code && code <= 0x135F)
      || (0x1712 <= code && code <= 0x1714)
      || (0x1732 <= code && code <= 0x1734)
      || (0x1752 <= code && code <= 0x1753)
      || (0x1772 <= code && code <= 0x1773)
      || (0x17B4 <= code && code <= 0x17B5)
      || (0x17B7 <= code && code <= 0x17BD)
      || (code == 0x17C6)
      || (0x17C9 <= code && code <= 0x17D3)
      || (code == 0x17DD)
      || (0x180B <= code && code <= 0x180D)
      || (0x1885 <= code && code <= 0x1886)
      || (code == 0x18A9)
      || (0x1920 <= code && code <= 0x1922)
      || (0x1927 <= code && code <= 0x1928)
      || (code == 0x1932)
      || (0x1939 <= code && code <= 0x193B)
      || (0x1A17 <= code && code <= 0x1A18)
      || (code == 0x1A1B)
      || (code == 0x1A56)
      || (0x1A58 <= code && code <= 0x1A60)
      || (code == 0x1A62)
      || (0x1A65 <= code && code <= 0x1A6C)
      || (0x1A73 <= code && code <= 0x1A7F)
      || (0x1AB0 <= code && code <= 0x1B03)
      || (code == 0x1B34)
      || (0x1B36 <= code && code <= 0x1B3A)
      || (code == 0x1B3C)
      || (code == 0x1B42)
      || (0x1B6B <= code && code <= 0x1B73)
      || (0x1B80 <= code && code <= 0x1B81)
      || (0x1BA2 <= code && code <= 0x1BA5)
      || (0x1BA8 <= code && code <= 0x1BA9)
      || (0x1BAB <= code && code <= 0x1BAD)
      || (code == 0x1BE6)
      || (0x1BE8 <= code && code <= 0x1BE9)
      || (code == 0x1BED)
      || (0x1BEF <= code && code <= 0x1BF1)
      || (0x1C2C <= code && code <= 0x1C33)
      || (0x1C36 <= code && code <= 0x1C37)
      || (0x1CD0 <= code && code <= 0x1CD2)
      || (0x1CD4 <= code && code <= 0x1CE0)
      || (0x1CE2 <= code && code <= 0x1CE8)
      || (code == 0x1CED)
      || (code == 0x1CF4)
      || (0x1CF8 <= code && code <= 0x1CF9)
      || (0x1DC0 <= code && code <= 0x1DFF)
      || (0x20D0 <= code && code <= 0x20F0)
      || (0x2CEF <= code && code <= 0x2CF1)
      || (code == 0x2D7F)
      || (0x2DE0 <= code && code <= 0x2DFF)
      || (0x302A <= code && code <= 0x302D)
      || (0x3099 <= code && code <= 0x309A)
      || (0xA66F <= code && code <= 0xA672)
      || (0xA674 <= code && code <= 0xA67D)
      || (0xA69E <= code && code <= 0xA69F)
      || (0xA6F0 <= code && code <= 0xA6F1)
      || (code == 0xA802)
      || (code == 0xA806)
      || (code == 0xA80B)
      || (0xA825 <= code && code <= 0xA826)
      || (0xA8C4 <= code && code <= 0xA8C5)
      || (0xA8E0 <= code && code <= 0xA8F1)
      || (code == 0xA8FF)
      || (0xA926 <= code && code <= 0xA92D)
      || (0xA947 <= code && code <= 0xA951)
      || (0xA980 <= code && code <= 0xA982)
      || (code == 0xA9B3)
      || (0xA9B6 <= code && code <= 0xA9B9)
      || (0xA9BC <= code && code <= 0xA9BD)
      || (code == 0xA9E5)
      || (0xAA29 <= code && code <= 0xAA2E)
      || (0xAA31 <= code && code <= 0xAA32)
      || (0xAA35 <= code && code <= 0xAA36)
      || (code == 0xAA43)
      || (code == 0xAA4C)
      || (code == 0xAA7C)
      || (code == 0xAAB0)
      || (0xAAB2 <= code && code <= 0xAAB4)
      || (0xAAB7 <= code && code <= 0xAAB8)
      || (0xAABE <= code && code <= 0xAABF)
      || (code == 0xAAC1)
      || (0xAAEC <= code && code <= 0xAAED)
      || (code == 0xAAF6)
      || (code == 0xABE5)
      || (code == 0xABE8)
      || (code == 0xABED)
      || (code == 0xFB1E)
      || (0xFE00 <= code && code <= 0xFE0F)
      || (0xFE20 <= code && code <= 0xFE2F)
      || (code == 0x101FD)
      || (code == 0x102E0)
      || (0x10376 <= code && code <= 0x1037A)
      || (0x10A01 <= code && code <= 0x10A0F)
      || (0x10A38 <= code && code <= 0x10A3F)
      || (0x10AE5 <= code && code <= 0x10AE6)
      || (0x10D24 <= code && code <= 0x10D27)
      || (0x10F46 <= code && code <= 0x10F50)
      || (code == 0x11001)
      || (0x11038 <= code && code <= 0x11046)
      || (0x1107F <= code && code <= 0x11081)
      || (0x110B3 <= code && code <= 0x110B6)
      || (0x110B9 <= code && code <= 0x110BA)
      || (0x11100 <= code && code <= 0x11102)
      || (0x11127 <= code && code <= 0x1112B)
      || (0x1112D <= code && code <= 0x11134)
      || (code == 0x11173)
      || (0x11180 <= code && code <= 0x11181)
      || (0x111B6 <= code && code <= 0x111BE)
      || (0x111C9 <= code && code <= 0x111CC)
      || (0x1122F <= code && code <= 0x11231)
      || (code == 0x11234)
      || (0x11236 <= code && code <= 0x11237)
      || (code == 0x1123E)
      || (code == 0x112DF)
      || (0x112E3 <= code && code <= 0x112EA)
      || (0x11300 <= code && code <= 0x11301)
      || (0x1133B <= code && code <= 0x1133C)
      || (code == 0x11340)
      || (0x11366 <= code && code <= 0x11374)
      || (0x11438 <= code && code <= 0x1143F)
      || (0x11442 <= code && code <= 0x11444)
      || (code == 0x11446)
      || (code == 0x1145E)
      || (0x114B3 <= code && code <= 0x114B8)
      || (code == 0x114BA)
      || (0x114BF <= code && code <= 0x114C0)
      || (0x114C2 <= code && code <= 0x114C3)
      || (0x115B2 <= code && code <= 0x115B5)
      || (0x115BC <= code && code <= 0x115BD)
      || (0x115BF <= code && code <= 0x115C0)
      || (0x115DC <= code && code <= 0x115DD)
      || (0x11633 <= code && code <= 0x1163A)
      || (code == 0x1163D)
      || (0x1163F <= code && code <= 0x11640)
      || (code == 0x116AB)
      || (code == 0x116AD)
      || (0x116B0 <= code && code <= 0x116B5)
      || (code == 0x116B7)
      || (0x1171D <= code && code <= 0x1171F)
      || (0x11722 <= code && code <= 0x11725)
      || (0x11727 <= code && code <= 0x1172B)
      || (0x1182F <= code && code <= 0x11837)
      || (0x11839 <= code && code <= 0x1183A)
      || (0x119D4 <= code && code <= 0x119DB)
      || (code == 0x119E0)
      || (0x11A01 <= code && code <= 0x11A06)
      || (0x11A09 <= code && code <= 0x11A0A)
      || (0x11A33 <= code && code <= 0x11A38)
      || (0x11A3B <= code && code <= 0x11A3E)
      || (code == 0x11A47)
      || (0x11A51 <= code && code <= 0x11A56)
      || (0x11A59 <= code && code <= 0x11A5B)
      || (0x11A8A <= code && code <= 0x11A96)
      || (0x11A98 <= code && code <= 0x11A99)
      || (0x11C30 <= code && code <= 0x11C3D)
      || (0x11C92 <= code && code <= 0x11CA7)
      || (0x11CAA <= code && code <= 0x11CB0)
      || (0x11CB2 <= code && code <= 0x11CB3)
      || (0x11CB5 <= code && code <= 0x11CB6)
      || (0x11D31 <= code && code <= 0x11D45)
      || (code == 0x11D47)
      || (0x11D90 <= code && code <= 0x11D91)
      || (code == 0x11D95)
      || (code == 0x11D97)
      || (0x11EF3 <= code && code <= 0x11EF4)
      || (0x16AF0 <= code && code <= 0x16AF4)
      || (0x16B30 <= code && code <= 0x16B36)
      || (code == 0x16F4F)
      || (0x16F8F <= code && code <= 0x16F92)
      || (0x1BC9D <= code && code <= 0x1BC9E)
      || (0x1D167 <= code && code <= 0x1D169)
      || (0x1D17B <= code && code <= 0x1D182)
      || (0x1D185 <= code && code <= 0x1D18B)
      || (0x1D1AA <= code && code <= 0x1D1AD)
      || (0x1D242 <= code && code <= 0x1D244)
      || (0x1DA00 <= code && code <= 0x1DA36)
      || (0x1DA3B <= code && code <= 0x1DA6C)
      || (code == 0x1DA75)
      || (code == 0x1DA84)
      || (0x1DA9B <= code && code <= 0x1E02A)
      || (0x1E130 <= code && code <= 0x1E136)
      || (0x1E2EC <= code && code <= 0x1E2EF)
      || (0x1E8D0 <= code && code <= 0x1E8D6)
      || (0x1E944 <= code && code <= 0x1E94A)
      || (0xE0100 <= code && code <= 0xE01EF);
};

Solution 22 - Javascript

function reverseString(string) {
    var reversedString = "";
    var stringLength = string.length - 1;
    for (var i = stringLength; i >= 0; i--) {
        reversedString += string[i];
    }
    return reversedString;
}

Solution 23 - Javascript

The real answer is: you can't reverse it in place, but you can create a new string that is the reverse.

Just as an exercise to play with recursion: sometimes when you go to an interview, the interviewer may ask you how to do this using recursion, and I think the "preferred answer" might be "I would rather not do this in recursion as it can easily cause a stack overflow" (because it is O(n) rather than O(log n). If it is O(log n), it is quite difficult to get a stack overflow -- 4 billion items could be handled by a stack level of 32, as 2 ** 32 is 4294967296. But if it is O(n), then it can easily get a stack overflow.

Sometimes the interviewer will still ask you, "just as an exercise, why don't you still write it using recursion?" And here it is:

String.prototype.reverse = function() {
	if (this.length <= 1) return this;
	else return this.slice(1).reverse() + this.slice(0,1);
}

test run:

var s = "";
for(var i = 0; i < 1000; i++) {
	s += ("apple" + i);
}
console.log(s.reverse());

output:

999elppa899elppa...2elppa1elppa0elppa

To try getting a stack overflow, I changed 1000 to 10000 in Google Chrome, and it reported:

RangeError: Maximum call stack size exceeded

Solution 24 - Javascript

I think String.prototype.reverse is a good way to solve this problem; the code as below;

String.prototype.reverse = function() {
  return this.split('').reverse().join('');
}

var str = 'this is a good example for string reverse';
str.reverse();
-> "esrever gnirts rof elpmaxe doog a si siht";

Solution 25 - Javascript

Strings themselves are immutable, but you can easily create a reversed copy with the following code:

function reverseString(str) {
  
  var strArray = str.split("");
  strArray.reverse();
  
  var strReverse = strArray.join("");

  return strReverse;
}

reverseString("hello");

Solution 26 - Javascript

//es6
//array.from
const reverseString = (string) => Array.from(string).reduce((a, e) => e + a);
//split
const reverseString = (string) => string.split('').reduce((a, e) => e + a); 

//split problem
"𠜎𠺢".split('')[0] === Array.from("𠜎𠺢")[0] // "�" === "𠜎" => false
"😂😹🤗".split('')[0] === Array.from("😂😹🤗")[0] // "�" === "😂" => false

Solution 27 - Javascript

Reverse a String using built-in functions

function reverse(str) {
  // Use the split() method to return a new array
  //  Use the reverse() method to reverse the new created array
  // Use the join() method to join all elements of the array into a string
  return str.split("").reverse().join("");
}
console.log(reverse('hello'));


Reverse a String without the helpers

function reversedOf(str) {
  let newStr = '';
  for (let char of str) {
    newStr = char + newStr
    // 1st round: "h" + "" = h, 2nd round: "e" + "h" = "eh" ... etc. 
    // console.log(newStr);
  }
  return newStr;
}
console.log(reversedOf('hello'));

Solution 28 - Javascript

Using Array functions,

String.prototype.reverse = function(){
    return [].reduceRight.call(this, function(last, secLast){return last + secLast});
}

Solution 29 - Javascript

var str = "my name is saurabh ";
var empStr='',finalString='';
var chunk=[];
function reverse(str){
var i,j=0,n=str.length;
	for(i=0;i<n;++i){
		if(str[i]===' '){
			chunk[j]=empStr;
			empStr = '';
			j++;
		}else{
			empStr=empStr+str[i];
		}
	}
	for(var z=chunk.length-1;z>=0;z--){
		finalString = finalString +' '+ chunk[z];
		console.log(finalString);
	}
	return true;
}
reverse(str);

Solution 30 - Javascript

Here's a basic ES6 immutable example without using Array.prototype.reverse:

// :: reverse = String -> String
const reverse = s => [].reduceRight.call(s, (a, b) => a + b)

console.log(reverse('foo')) // => 'oof'
console.log(reverse('bar')) // => 'rab'
console.log(reverse('foo-bar')) // => 'rab-oof'

Solution 31 - Javascript

Best ways to reverse a string in JavaScript

1) Array.reverse:

You’re probably thinking, wait I thought we were reversing a string, why are you using the Array.reverse method. Using the String.split method we are converting our string into an Array of characters. Then we are reversing the order of each value in the array and then finally we convert the Array back to a String using the Array.join method.

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

2) Decrementing while-loop:

Although pretty verbose, this solution does have its advantages over solution one. You’re not creating an array and you’re just concatenating a string based on characters from the source string.

From a performance perspective, this one would probably yield the best results (although untested). For extremely long strings, the performance gains might drop out the window though.

function reverseString(str) {
    var temp = '';
    var i = str.length;

    while (i > 0) {
        temp += str.substring(i - 1, i);
        i--;
    }


    return temp;
}
reverseString('dwayne');

3) Recursion

I love how simple and clear this solution is. You can clearly see that the String.charAt and String.substr methods are being used to pass through a different value by calling itself each time until the string is empty of which the ternary would just return an empty string instead of using recursion to call itself. This would probably yield the second best performance after the second solution.

function reverseString(str) {
    return (str === '') ? '' : reverseString(str.substr(1)) + str.charAt(0);
}
reverseString('dwayne');

Solution 32 - Javascript

My own original attempt...

var str = "The Car";

function reverseStr(str) {
  var reversed = "";
  var len = str.length;
  for (var i = 1; i < (len + 1); i++) {  
    reversed += str[len - i];      
  }
  
  return reversed;
}
 
var strReverse = reverseStr(str);    
console.log(strReverse);
// "raC ehT"

http://jsbin.com/bujiwo/19/edit?js,console,output

Solution 33 - Javascript

Keep it DRY and simple silly!!

function reverse(s){
let str = s;
var reverse = '';
for (var i=str.length;i>0;i--){

    var newstr = str.substring(0,i)
    reverse += newstr.substr(-1,1)
}
return reverse;
}

Solution 34 - Javascript

OK, pretty simple, you can create a function with a simple loop to do the string reverse for you without using reverse(), charAt() etc like this:

For example you have this string:

var name = "StackOverflow";

Create a function like this, I call it reverseString...

function reverseString(str) {
  if(!str.trim() || 'string' !== typeof str) {
    return;
  }
  let l=str.length, s='';
  while(l > 0) {
    l--;
    s+= str[l];
  }
  return s;
}

And you can call it like:

reverseString(name);

And the result will be:

"wolfrevOkcatS"

Solution 35 - Javascript

Here are the four most common methods you can use to achieve a string reversal

Given a string, return a new string with the reversed order of characters

Multiple Solutions to the problem

//reverse('apple') === 'leppa'
//reverse('hello') === 'olleh'
//reverse('Greetings!') === '!sgniteerG'

// 1. First method without using reverse function and negative for loop
function reverseFirst(str) {
    if(str !== '' || str !==undefined || str !== null) {
        const reversedStr = [];
        for(var i=str.length; i>-1; i--) {
        reversedStr.push(str[i]);
        }
    return reversedStr.join("").toString();
    }
}

// 2. Second method using the reverse function
function reverseSecond(str) {
    return str.split('').reverse().join('');
}

// 3. Third method using the positive for loop
function reverseThird(str){
    const reversedStr = [];
    for(i=0; i<str.length;i++) {
        reversedStr.push(str[str.length-1-i])
    }
    return reversedStr.join('').toString();
}

// 4. using the modified for loop ES6
function reverseForth(str) {
    const reversedStr = [];
    for(let character of str) {
        reversedStr = character + reversedStr;
    }
    return reversedStr;
}

// 5. Using Reduce function
function reverse(str) {
    return str.split('').reduce((reversed, character) => {
        return character + reversed;  
    }, '');
}

Solution 36 - Javascript

use this method if you are more curious about performance and time complexity. in this method i have divided string in two part and sort it in length/2 times loop iteration.

let str = "abcdefghijklmnopqrstuvwxyz"

function reverse(str){
let store = ""
let store2 = ""

for(let i=str.length/2;i>=0;i--){
  if(str.length%2!==0){
     store += str.charAt(i) 
  store2 += str.slice((str.length/2)+1, str.length).charAt(i)
  }else{
store += str.charAt(i-1) 
  store2 += str.slice((str.length/2), str.length).charAt(i)
  }
  
}
return store2+store
}

console.log(reverse(str))

it is not optimal but we can think like this.

Solution 37 - Javascript

ES6

 function reverseString(str) {
     return [...str].reverse().join("");
 }

 console.log(reverseString("Hello")); // olleH

Solution 38 - Javascript

You could try something like this. I'm sure there's some room for refactoring. I couldn't get around using the split function. Maybe someone knows of a way to do it without split.

Code to set up, can put this in your .js library

Code to use it (has client side code, only because it was tested in a browser):

var sentence = "My Stack is Overflowing."
document.write(sentence.reverseLetters() + '<br />');
document.write(sentence.reverseWords() + '<br />');

Snippet:

String.prototype.aggregate = function(vals, aggregateFunction) {

  var temp = '';
  for (var i = vals.length - 1; i >= 0; i--) {
    temp = aggregateFunction(vals[i], temp);
  }
  return temp;
}

String.prototype.reverseLetters = function() {
  return this.aggregate(this.split(''),
    function(current, word) {
      return word + current;
    })
}

String.prototype.reverseWords = function() {
  return this.aggregate(this.split(' '),
    function(current, word) {
      return word + ' ' + current;
    })
}

var sentence = "My Stack is Overflowing."
document.write(sentence.reverseLetters() + '<br />');
document.write(sentence.reverseWords() + '<br />');

Solution 39 - Javascript

Another variation (does it work with IE?):

String.prototype.reverse = function() {
    for (i=1,s=""; i<=this.length; s+=this.substr(-i++,1)) {}
    return s;
}

EDIT:

This is without the use of built-in functions:

String.prototype.reverse = function() {
    for (i=this[-1],s=""; i>=0; s+=this[i--]) {}
    return s;
}

Note: this[-1] holds a length of the string.

However it's not possible to reverse the string in place, since the assignment to individual array elements doesn't work with String object (protected?). I.e. you can do assigns, but the resulting string doesn't change.

Solution 40 - Javascript

var str = "IAMA JavaScript Developer";
var a=str.split(''), b = a.length;
for (var i=0; i<b; i++) {
    a.unshift(a.splice(1+i,1).shift())
}
a.shift();
alert(a.join(''));

Solution 41 - Javascript

function reverse_string(string)
{
var string;

var len = string.length;

var stringExp = string.split('');
var i;
for (i = len-1; i >=0;i--)
{
var result = document.write(stringExp[i]);
}

return result;
}

reverse_string("This is a reversed string");

//outputs: gnirts desrever a si sihT

Solution 42 - Javascript

without converting string to array;

String.prototype.reverse = function() {

    var ret = "";
    var size = 0;

    for (var i = this.length - 1; -1 < i; i -= size) {

        if (
          '\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' && 
          '\uDC00' <= this[i]     && this[i]     <= '\uDFFF'
        ) {
            size = 2;
            ret += this[i - 1] + this[i];
        } else {
            size = 1;
            ret += this[i];
        }
    }

    return ret;
}

console.log('anãnam anañam' === 'mañana mañana'.reverse());

using Array.reverse without converting characters to code points;

String.prototype.reverse = function() {

    var array = this.split("").reverse();

    for (var i = 0; i < this.length; ++i) {

        if (
          '\uD800' <= this[i - 1] && this[i - 1] <= '\uDBFF' && 
          '\uDC00' <= this[i]     && this[i]     <= '\uDFFF'
        ) {
            array[i - 1] = array[i - 1] + array[i];
            array[i] = array[i - 1].substr(0, 1);
            array[i - 1] = array[i - 1].substr(1, 1);
        }

    }

    return array.join("");
}

console.log('anãnam anañam' === 'mañana mañana'.reverse());

Solution 43 - Javascript

function reverse(str){
var s = "";
for (var i = str.length - 1; i >= 0; i--){
    s += str[i];
}
return s;
};
reverse("your string comes here")

Solution 44 - Javascript

The below might help anyone that is looking to reverse a string recursively. Was asked to do this in a recent job interview using functional programming style:

var reverseStr = function(str) {
    return (str.length > 0) ? str[str.length - 1] + reverseStr(str.substr(0, str.length -   1)) : '';
};

//tests
console.log(reverseStr('setab retsam')); //master bates

Solution 45 - Javascript

Adding to the String prototype is ideal (just in case it gets added into the core JS language), but you first need to check if it exists, and add it if it doesn't exist, like so:

String.prototype.reverse = String.prototype.reverse || function () {
    return this.split('').reverse().join('');
};

Solution 46 - Javascript

Something like this should be done following the best practices:

(function(){
	'use strict';
	var str = "testing";
	
	//using array methods
	var arr = new Array();
	arr = str.split("");
	arr.reverse();
	console.log(arr);
	
	//using custom methods
	var reverseString = function(str){
		
		if(str == null || str == undefined || str.length == 0 ){
			return "";
		}
		
		if(str.length == 1){
			return str;
		}
		
		var rev = [];
		for(var i = 0; i < str.length; i++){
			rev[i] = str[str.length - 1 - i];
		}
		return rev;
	} 
	
	console.log(reverseString(str));
	
})();

Solution 47 - Javascript

var reverseString = function(str){ 
  let length = str.length - 1;
  str = str.split('');

  for(let i=0;i<= length;i++){
    str[length + i + 1] = str[length - i];
  }

  return str.splice(length + 1).join('');
}

Solution 48 - Javascript

No built-in methods? Given that strings in Javascript are immutable, you probably want to use the in-built methods like split, join, and so on. But here are two ways to go without those methods:

function ReverseString(str) {
    var len = str.length;
    var newString = [];

    while (len--) {
        newString.push(str[len]);
    }

    return newString.join('');
}

console.log(ReverseString('amgod')) //dogma

function RecursiveStringReverse(str, len) {
    if (len === undefined)
        len = str.length - 1;
    
    if (len > 0)
        return str[len] + RecursiveReverse(str, --len);

    return str[len];
}

console.log(RecursiveStringReverse('Hello, world!'))// !dlrow ,olleH

Solution 49 - Javascript

Added for reverse of string without loop, it's working through recursion.

function reverse(y){
	if(y.length==1 || y.length == 0 ){
		return y;
	}
	return y.split('')[y.length - 1]+ reverse(y.slice(0, y.length-1));
}
console.log(reverse("Hello"));

Solution 50 - Javascript

    function reverse(string)
    {
    let arr = [];
    for(let char of string) {
      arr.unshift(char);
    }
    let rev = arr.join('')
    return rev
    }
    
    let result = reverse("hello")
    console.log(result)

Solution 51 - Javascript

We can iterate the string array from both the ends: start and end, and swap at each iteration.

function reverse(str) {
 let strArray = str.split("");
 let start = 0;
 let end = strArray.length - 1;

 while(start <= end) {
  let temp = strArray[start];
  strArray[start] = strArray[end];
  strArray[end] = temp;

  start++;
  end--;
 }
 return strArray.join("");
}

Although the number of operations have reduced, its time complexity is still O(n) as the number of operations still scale linearly with the size of input.

Ref: AlgoDaily

Solution 52 - Javascript

One of the way could also be using reduce method to reverse after using split method.

function reverse(str) {
    return str.split('').reduce((rev, currentChar) => currentChar + rev, '');
}
  console.log(reverse('apple'));
  console.log(reverse('hello'));
  console.log(reverse('Greetings!'));

Solution 53 - Javascript

function reverseWords(str) {
  // Go for it
  const invertirPalabra = palabra => palabra.split('').reverse().join('')
  return str.split(' ').map(invertirPalabra).join(' ')
  // con split convierto string en array de palabras, le paso ' ' 
  // que es que me lo separe por espacios
  // luego invierto cada palabra...
  // y luego con join las uno separando por espacios
}

Solution 54 - Javascript

// try this simple way

const reverseStr = (str) => {
    let newStr = "";
    for (let i = str.length - 1; i >= 0; i--) {
        newStr += str[i];
    }
    return newStr;
}
console.log(reverseStr("ABCDEFGH")); //HGFEDCBA

Solution 55 - Javascript

//recursive implementation
function reverse(wrd) {
  const str =wrd[0]
  if(!wrd.length) {
    return wrd
  }
  return reverse(wrd.slice(1)) + str
}

Solution 56 - Javascript

I guess, this will work for you

function reverse(str){
    str = str.split("").reverse().join("").split(" ").reverse().join(" ");
    console.log(str)
}

Solution 57 - Javascript

word.split('').reduce((acc, curr) => curr+""+acc)

Solution 58 - Javascript

It is not possible to reverse a string in place, but it is possible to do it not in place.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJakeView Question on Stackoverflow
Solution 1 - JavascriptbelacquaView Answer on Stackoverflow
Solution 2 - JavascriptMathias BynensView Answer on Stackoverflow
Solution 3 - JavascriptBobView Answer on Stackoverflow
Solution 4 - JavascriptAnil ArraboleView Answer on Stackoverflow
Solution 5 - JavascriptMozleronView Answer on Stackoverflow
Solution 6 - JavascriptMichał PerłakowskiView Answer on Stackoverflow
Solution 7 - JavascriptprogramkingView Answer on Stackoverflow
Solution 8 - JavascriptninjageckoView Answer on Stackoverflow
Solution 9 - JavascriptHussain ThajutheenView Answer on Stackoverflow
Solution 10 - JavascriptDr.GView Answer on Stackoverflow
Solution 11 - JavascriptMaher HossainView Answer on Stackoverflow
Solution 12 - JavascriptAlex HawkinsView Answer on Stackoverflow
Solution 13 - JavascriptDavaakhuu ErdenekhuuView Answer on Stackoverflow
Solution 14 - JavascriptFatih AcetView Answer on Stackoverflow
Solution 15 - JavascriptYogeshView Answer on Stackoverflow
Solution 16 - Javascriptjitendra rajputView Answer on Stackoverflow
Solution 17 - JavascriptScott GartnerView Answer on Stackoverflow
Solution 18 - JavascriptKamil KiełczewskiView Answer on Stackoverflow
Solution 19 - JavascriptNick ParsonsView Answer on Stackoverflow
Solution 20 - JavascriptGiacomo CasadeiView Answer on Stackoverflow
Solution 21 - JavascriptMT0View Answer on Stackoverflow
Solution 22 - JavascriptGR1000View Answer on Stackoverflow
Solution 23 - JavascriptnonopolarityView Answer on Stackoverflow
Solution 24 - JavascriptjingyinggongView Answer on Stackoverflow
Solution 25 - JavascriptRamsy de VosView Answer on Stackoverflow
Solution 26 - JavascriptalejandroView Answer on Stackoverflow
Solution 27 - JavascriptDzenis H.View Answer on Stackoverflow
Solution 28 - JavascriptDarshanView Answer on Stackoverflow
Solution 29 - JavascriptRobinView Answer on Stackoverflow
Solution 30 - JavascriptAlan R. SoaresView Answer on Stackoverflow
Solution 31 - JavascriptMohit Kumar GuptaView Answer on Stackoverflow
Solution 32 - JavascriptAntonBView Answer on Stackoverflow
Solution 33 - JavascriptSagar MunjalView Answer on Stackoverflow
Solution 34 - JavascriptAlirezaView Answer on Stackoverflow
Solution 35 - JavascriptHarshit PantView Answer on Stackoverflow
Solution 36 - Javascriptmanan5439View Answer on Stackoverflow
Solution 37 - JavascriptAmr AliView Answer on Stackoverflow
Solution 38 - JavascriptJustin LargeyView Answer on Stackoverflow
Solution 39 - JavascriptThevsView Answer on Stackoverflow
Solution 40 - JavascriptNathan RomanoView Answer on Stackoverflow
Solution 41 - JavascriptSteven McsorleyView Answer on Stackoverflow
Solution 42 - JavascriptmasakielasticView Answer on Stackoverflow
Solution 43 - JavascriptHenry LynxView Answer on Stackoverflow
Solution 44 - JavascriptAlex HawkinsView Answer on Stackoverflow
Solution 45 - JavascriptcharlchadView Answer on Stackoverflow
Solution 46 - JavascriptPritam BanerjeeView Answer on Stackoverflow
Solution 47 - JavascriptYazan RawashdehView Answer on Stackoverflow
Solution 48 - JavascriptWesleyACView Answer on Stackoverflow
Solution 49 - JavascriptChandan SinghView Answer on Stackoverflow
Solution 50 - JavascriptmuqsithView Answer on Stackoverflow
Solution 51 - JavascriptKJ SudarshanView Answer on Stackoverflow
Solution 52 - JavascriptVikas GuptaView Answer on Stackoverflow
Solution 53 - JavascriptAna Gabriela GuzmanView Answer on Stackoverflow
Solution 54 - JavascriptForce BoltView Answer on Stackoverflow
Solution 55 - Javascripthamza ahmadView Answer on Stackoverflow
Solution 56 - JavascriptM Sohaib KhanView Answer on Stackoverflow
Solution 57 - JavascriptParth ChokshiView Answer on Stackoverflow
Solution 58 - JavascriptVappor WashmadeView Answer on Stackoverflow