Overview
Simply, everything inside the square brackets shows an optional parameter. When you have square brackets inside other square brackets, it means that the second square brackets are only valid if the first square brackets were used.
First documentation
str.count(sub[, start[, end]])
The documentation shows this: str.count(sub[, start[, end]])
. Each variable inside ( )
(so sub
, start
and end
) are parameters.
Lets start off with a simpler example. Imagine instead the documentation only allowed for two parameters like so: str.count(sub, start)
. The problem here is that start
is optional! The user only has to include it if they want to start the search from somewhere other than the start of the string.
The solution to this, is to always include optional parameters inside [ ]
. So this means our new documentation is: str.count(sub[, start])
.
The reason the comma is inside the [ ]
is because you can almost think of "removing" everything inside the [ ]
. If the comma was outside, like this: str.count(sub, [start])
and you removed everything inside the [ ]
, then it would look like: str.count(sub, )
which we can see is wrong.
First documentation, further explanation
So that's the reason behind the funny comma [ ]
thing that you've seen. But then the question of "why are there things like [, [ ]]
???" remains.
The answer: because some optional parameters depend on others. In this case, the end
parameter can only be used if the start
parameter has been used. If we tried our previous rule and kept both start
and end
inside the same [ ]
, then we get: str.count(sub[, start, end])
.
This is wrong, because it suggests that we can only use both optional parameters or none of the parameters, since if we removed the [ ]
we get: str.count(sub)
. There is no inbetween here.
To tell our users this, we put the second [ ]
inside the first, so that the second optional parameter is only usable if the first has been used. So if we want to only use the start
optional parameter, we keep the first [ ]
, and remove the second [ ]
(which are inside the first), meaning that str.count(sub[, start[, end]])
becomes str.count(sub, start)
. We have only removed the inner-most [ ]
.
Using this new system of [, [ ]]
, it also means that we can't just use the end
parameter, since to remove start
we have to remove the outside [ ]
, but this also removes the inside [ ]
which then removes end
.
First documentation, further further explanation
"But what if we want to be able to use any combination of the two?" You don't. If we did something like: str.count(sub[, start][, end])
this means we can have any combination of start
and end
.
This breaks things because if we only use the end
parameter, there's no way of telling if its start
or end
! If we use str.count(sub[, start][, end])
, we don't know if str.count(sub, 5)
means that we want to start at index 5
, or end at index 5
.
Second documentation
emitter.emit(eventName[, ...args])
This example is almost exactly the same as before, except the ...
is actually an operator in JavaScript.
Using our new knowledge, we can tell that emitter.emit
has one required parameter eventName
(as its not inside [ ]
), and one optional parameter [, ...args]
.
The ...
simply means: "get all extra parameters provided after this point, and put them into an array".
So for an example:
function hello(name, ...extraNames) {
console.log(extraNames);
console.log('hi ' + name);
for (let i=0; i<extraNames.length; i++) {
console.log('hi extra name ' + extraNames[i]);
}
}
hello('dan')
// []
// hi dan
hello('dan', 'frank', 'mark')
// ['frank', 'mark']
// hi dan
// hi extra name frank
// hi extra name mark
And the reason that the , ...args
is inside [ ]
is because those extra parameters (known as rest parameters) are always optional. They are always for catching extra parameters passed, and therefore also have to come last in the function definition.
The equivalent of the ...
parameter in Python are *args
(arguments), used like so:
def hello(name, *extraNames):
print(extraNames)
print('hi ' + name)
for extraName in extraNames:
print('hi extra name ' + extraName)
hello('dan')
# []
# hi dan
hello('dan', 'frank', 'mark')
# ['frank', 'mark']
# hi dan
# hi extra name frank
# hi extra name mark
Also look into **kwargs
(key word arguments) which allow you to have any number of "key value pairs" given as a dictionary such as this:
def hello(**kwargs):
print(kwargs)
for key in kwargs:
print(key + ' equals ' + kwargs[key])
hello('one'='apple', 'two'='orange')
# {'one'='apple', 'two'='orange'}
# one equals apple
# two equals orange
JavaScript doesn't have an equivalent to this, but you can always pass an object of values as your "kwargs".
Hope this helps!