Reverse Vowels of a String
I recommend using the Array.prototype methods. 

These lend themselves to adopting a functional style of programming.

Functional programming is a lot easier to test, as a pure function always returns the same result and never mutate objects. 



const vowels = ['a','e','i','o','u']; 
function vowelStringReverse(str) {
  
    //split the string into an array of chars, that includes their index position
    const strArray = str.split('').map((v,i) =&gt; ({
        value: v, 
        i: i, 
        isVowel: vowels.includes(v)
    })); 
    
    //For just the vowels, 
    //Create index position lookup, where the index positions are reversed
    const vowelsReverseIndexLookup = strArray.filter(v =&gt; v.isVowel)
    .reduce((acc, cur, i, array) =&gt; {
        return {
            ...acc, 
            [array[array.length-1-i].i]: cur.value
        }; 
    
    }, {}); 
    
    //Now iterate through the string, and look up the vowel from the lookup. 
    const strReversed = strArray.map((v,i) =&gt; {
        if (v.isVowel) {
            return vowelsReverseIndexLookup[i]
        }
        else {
            return v.value; 
        }
    }); 
    
    return strReversed.join(''); 
    
}


console.log(vowelStringReverse('hello')); 
console.log(vowelStringReverse('leetcode')); 




In this example I've given, if you wanted, you could then pull out the anonymous functions I've declared, and write tests for them: 

for example: 

const vowelsReverseIndexLookup = strArray.filter(v =&gt; v.isVowel)
.reduce(reverseIndexReducer, {}); 

//elsewhere: 

const reverseIndexReducer = (acc, cur, i, array) =&gt; {
    return {
        ...acc, 
        [array[array.length-1-i].i]: cur.value
    }; 

};