From this msdn documentation for the matching method:
If global flag (g) is not set, the zero element of the array contains all matches, and elements 1 through n contain submatrices. This behavior is the same as exec (regular expression) (JavaScript) behavior when the global flag is not set. If the global flag is set, items 0 through n contain all matches that have occurred.
Emphasis is mine.
So in your first case :
'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/g)
Since the /g modifier is installed, it will only return the complete matches that occurred, not the submatrices. This is why you just got an array with one element. Since there is only 1 match for this regular expression.
Second case :
'/links/51f5382e7b7993e335000015'.match(/^\/links\/([0-9a-f]{24})$/)
Modifier
/g not installed. So the array contains a complete match at index 0th . And then the elements (1st index) in the array are submatrices - in this case, the first capture group.
As for your last example :
'fofoofooofoooo'.match(/f(o+)/g)
Again, since the /g modifier is set, it will return all matches from the string, not the submatrix. So, in the string, the regular expression f(o+) matches 4 times:
fo - 1st complete match (sub-match 'o' in 1st captured group ignored) foo - 2nd complete match (sub-match 'oo' ignored) fooo - 3rd complete match (sub-match 'ooo' ignored) foooo - 4th complete match (sub-match 'oooo' ignored)
If you use the last regular expression without the /g modifier, you will get each profile as a separate element for the first match. Try:
'fofoofooofoooo'.match(/f(o+)/)
You'll get:
["fo", "o"] // With index and input element of course.
Without /g it just stops after the first match ( fo ) and returns all matches and matches.