I don't understand how permutations work

function permutations(string) {
  if (string.length <= 1) {
    return [string];
  }
  
  let finalPermutations = permutations(string.substring(1)) // how does this work?
    .reduce((acc, p) => { 
      let charList = p.split(''); 
      for (let i = 0; i <= charList.length; i++) { // how does this work?
        let newPermutation = charList.slice(0, i) // how does this work?
                              .concat([string[0]]) // how does this work?
                              .concat(charList.slice(i)) // how does this work?
                              .join(''); // how does this work?
        if (!acc.includes(newPermutation)) { // how does this work?
          acc.push(newPermutation); // how does this work?
        } 
      }
      return acc;      
  },[]);
  return finalPermutations;
}

It takes the string without the first character. "abcd""bcd".

For every length ("", "b", "bc", "bcd") it appends the first character (a) of the string.
"A", "bA", "bcA", "bcdA"

Then it appends the rest. → "aBCD", "baCD", "bcaD", "bcda"

Recursively