Find out whether string A can be shifted to get string B
You can check if the String is empty with !str instead of strA.length === 0, 

console.log(''); // false

i think haveSameLength and isSame are extras, you can write srtA.length === strB.length and it would still be readable,

you can get the first letter with a simpler strA[0] instead of strA.substring(0, 1);


  Which one is more readable and easier to understand for you?


a loop is easier to read and understand than a recursive function, 

But the hole approach seems like it can be simpler using a for loop, Array.some() , here's what i would suggest : 

You can generate an array of combinations moving the letters one index at a time,
for a string abc you would have ['abc, bca', 'cba'], see if one of the resulting array entries euqals the second string :



const isSameAfterShifting = (str1, str2) =&gt; {
  // check if the strings are empty or has different lengths
  if (!str1 || !str2 || str1.length !== str2.length) return false;

  // check if the strings are the same
  if (str1 === str2) return true;

  // generate the array 
  let combos = [];
  for (let i = 0; i &lt; str1.length; i++) {
    let c = str1.slice(i) + str1.slice(0, i);
    combos.push(c);
  }

  // for a string 'abc'
  // combos = ['abc', bca', 'cab']

  // check if the array has one of its entries equal to the second string  
  return combos.some(s =&gt; s === str2);
}

console.log( isSameAfterShifting('abc', 'cab') );
console.log( isSameAfterShifting('abc', 'cabaaa') );
console.log( isSameAfterShifting('abc', 'bac') );




you can replace the for loop with Array.from()



const isSameAfterShifting = (str1, str2) =&gt; {
  // check if the strings are empty or has different lengths
  if (!str1 || !str2 || str1.length !== str2.length) return false;

  // check if the strings are the same
  if (str1 === str2) return true;

  // generate the array
  let combos = Array.from({
    length: str1.length
  }, (_, i) =&gt; str1.slice(i) + str1.slice(0, i));

  // for a string 'abc'
  // combos = ['abc', bca', 'cab']

  // check if the array has one of its entries equal to the second string
  return combos.some(s =&gt; s === str2);
};

console.log(isSameAfterShifting("abc", "cab"));
console.log(isSameAfterShifting("abc", "cabaaa"));
console.log(isSameAfterShifting("abc", "bac"));