Basic Algorithm Scripting - Chunky Monkey

OK I have another question about a solution Im hoping to gain clarity on.

The task: Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a two-dimensional array.

The solution is listed below but this is the code I need some clarification on :
newArr.push(arr.slice(i, i + size))

If the first argument in slice() is the index location of where you want to start your copy and the 2nd argument is the index location of where you want to stop your copy…
AND size === 3, then i + size === 0 + 3…
then wouldnt that indicate to stop the copy at index[3], instead of the 3rd index of index[2]?

Does this question make sense? slice(0, 4) === start copy at index[0] and stop copy at index[4], correct?

function chunkArrayInGroups(arr, size) {
let newArr = [];
for (let i = 0; i < arr.length; i += size) {
  newArr.push(arr.slice(i, i + size));
}
return newArr;
}

chunkArrayInGroups(["a", "b", "c", "d"], 2);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0

Challenge: Basic Algorithm Scripting - Chunky Monkey

Link to the challenge:

Looking at MDN:

The slice() method returns a shallow copy of a portion of an array into a new array object selected from start to end (end not included)

So the end index is not copied.