When you see this in documentation:
response.writeHead(statusCode[, statusMessage][, headers])
...it means you can call that method in one of the following ways:
response.writeHead(statusCode)
response.writeHead(statusCode, statusMessage)
response.writeHead(statusCode, headers)
response.writeHead(statusCode, statusMessage, headers)
So the square brackets in the syntax notation denote that something is optional. This means also that the comma must appear like that.
Dangling Commas
Your second example is in fact a less accurate descriptor:
window.setTimeout(func, [delay, param1, param2, ...]);
because when taken too literally, it would seem to allow this:
window.setTimeout(func, );
but that is invalid syntax, at least in JavaScript what this syntax descriptor seems to be about.
Allowed Number of Arguments
The above descriptor does not clearly indicate that you can call this method with only 2 or 3 arguments, like for example:
window.setTimeout(alert('hi'), 100);
But clearly, this is understood to be the case. Some would prefer to write such a descriptor as:
window.setTimeout(func[, delay[, param1[, param2[, ...]]]]);
No-one will make an issue of the first descriptor: it is clear what is intended. It is part of documentation, not a strict language. In fact, the many brackets do not really add to the readability of such a descriptor. It is a matter of where to draw the line between exactness and clarity.
Ellipsis
Note also that the dots mean many more parameters could follow. This ellipsis is not to be taken as a literal either. This is not to be confused with ellipses that are part of some language syntaxes (e.g. Javascript spread operator). This shows again this documentation convention is not a very strict language.
Multiple Bracket Pairs
Back to the first example. Note that the described method has two pairs of brackets. This actually has a meaning, and expresses a possibility that is not visible in this alternative descriptor that only has one pair:
response.writeHead(statusCode[, statusMessage, headers])
The difference is that this alternative does not allow this call:
response.writeHead(statusCode, headers)
If one would want to pass headers, then they also have to provide statusMessage:
response.writeHead(statusCode, statusMessage, headers)
However, the original descriptor does allow this. This means the described method is quite smart, as it supports two different interpretations for calls that are made with 2 arguments:
response.writeHead(statusCode, statusMessage)
response.writeHead(statusCode, headers)
This is obviously because values that have the meaning of statusMessage are distinguishable from values that have the meaning of header. In this particular case, nodejs treats the second argument as a header when it is an object, and as a statusMessage when it is a primitive value (string).