In the form expression (...), () is the function-application operator. It takes in the expression on the left, which must be a function-object and invokes it, passing in the supplied parameters, if any. (The other use of () is for precedence, which includes (expression-that-evaluates-to-a-function-object).)
The "trick" is to understand this works for any expression that evaluates to a function-object and that a function-name simply evaluates to the function-object it represents. Here is a demonstration:
function f1 () { return 1 }
typeof f1 // function
f1() // 1
var f1b = f1 // f1 evaluates to a function-object which is assigned to f1b
f1b() // 1
var f2 = function () { return 2 }
typeof f2 // function
(((f2))()) // 2 -- only one of the sets is the application operator
typeof (function () {}) // function
(function () { return 3 })() // 3 -- any function-object can be applied
Happy coding.
One reason for using a self-invoking anonymous function is to "create a new scope". New scopes in JavaScript are only introduced by new functions.