The results wouldn't be the same at all. You can test this for yourself:
results = [1, 2, 3];
subArray = [4, 5, 6];
results.push(subArray);
console.log("With push:", results); // With push: [1, 2, 3, [4, 5, 6]]
results = [1, 2, 3]; // reset results
results.push.apply(results, subArray);
console.log("With apply:", results); // With apply: [1, 2, 3, 4, 5, 6]
apply accepts an array of arguments, and the elements of the array become individual arguments to the function.
This lets you invoke the function push with an arbitrary number of arguments, where each argument is added to the array. Simply calling results.push(...) would invoke the function with a single argument, which would be an array, resulting in the entire subArray being pushed onto results as one element.
In the above example, results.push.apply(results, subArray) is equivalent to calling results.push(4, 5, 6), while results.push(subArray) simply invokes results.push([4, 5, 6]).
The net effect of using one over the other is that, given an input array containing sub-arrays...
[[1, 2, 3], [4, 5, 6], [7, 8], [9]]
... using results.push would produce an identical array, where each sub-array was pushed onto results as a single element:
[[1, 2, 3], [4, 5, 6], [7, 8], [9]]
Using results.push.apply would cause each element from each sub-array to be pushed onto results as its own element, resulting in the desired flattened array:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
concat…return Array.prototype.concat.apply([], this)concattakes multiple arrays as arguments - and that's just what we give it withapply.