As has been mentioned already, the parentheses can be used to group operations to help control the evaluation of the expression. An example from simple math is: 2 + 3 * 4 = 14, but (2 + 3) * 4 = 20. With this understanding, let’s try to evaluate the expression you asked about:
let availableProducts = [item1, item2, item3, item4, …(product.available ? [this.getProduct(product)] : [])];
On the left side of the statement, we are assigning the value returned by the right side to the variable named availableProducts. Easy enough. It’s the right side that requires thought.
The first thing I notice is that the outer square brackets [] surrounding the expression tell me that the expression is returning, or evaluating to, an array. Next, I see that item1 through item4 are simple variables and require no explanation. They will occupy the first 4 slots in the resulting array (indexes 0 - 3).
Next, I notice the spread operator ... and have to ask what is it spreading? It’s spreading the expression (product.available ? [this.getProduct(product)] : []). The opening parenthesis is matched by the closing parenthesis. Let’s remove them, and work on evaluating the remaining expression:
product.available ? [this.getProduct(product)] : []
Now it looks like a fairly simple ternary expression. What does it return, or evaluate to? If product.available is truthy, it returns an array containing the return value of the function call this.getProduct(product). Otherwise, it returns an empty array []. The result of the ternary operation is spread into the array. Ultimately, it is either going to add the item from getProduct or nothing.