Same interface, very different performance and mutation behavior underneath.
Arrays bundle two very different concerns under one API: mutating methods (push, pop, splice, sort) that change the array in place, and non-mutating methods (map, filter, slice, concat) that return a new array and leave the original alone. Mixing these up unintentionally — like assuming sort() returns a new array — is one of the most common sources of subtle bugs, especially once arrays are shared across components or functions.
Performance also isn't uniform across methods. push/pop at the end of an array are O(1), while unshift/shift at the beginning are O(n) because every remaining element has to be re-indexed. Chaining several map/filter/reduce calls is readable but creates an intermediate array at every step, which matters for very large datasets — sometimes a single reduce or a plain for loop is the meaningfully faster choice, even if it's less elegant.
What you'll walk away knowing