Inside the body of an IIFE the return keyword can then be used as a way to go about returning something that can be stored in a variable outside of the IIFE. This something that is returned to an outside variable can be a plain old object with properties and methods, a function, or a function with static properties added that serves as a kind of public API. Private helper methods can then also be placed inside the IIFE that can then be used indirectly in the public methods.
The IIFE can also just be used as a way to not go about polluting the global name space, as everything that is defined within the body of an IIFE with var, let, or const will be local to the function rather than the top level or global object. Builds of projects are often made where all the front end code of a project is wrapped up into an IIFE. This helps to keep all the variables of a project from writing over anything else that might be global in a page.
The first and for most thing to write about here is that any variable that is defined in the body of an IIFE with the var keyword, or the more modern alternatives, will be local to the scope of that IIFE. This is not just true of an IIFE, but functions in general.
Arguments can be passed when calling it just like any other function, the only real difference is that it is being called right away, and only once. When it comes to arguments and functions one thing to point out is that the values can be copied by value if the value is a primitive values such as a number or string, but objects are a different story.
Whatever is returned by the IIFE will have a prototype object with it often. For example if what is returned by the IIFE is a Array then there will be Array prototype methods like map, and reduce to work with off of the result. Methods such as this can be called off of the end of the IIFE, inside the body of the IIFE when returning the result, or at a later point off of a variable if the result is stored to one.
So for a simple example say I have a global variable called count, and I attach an IIFE to it. Inside the body of the IIFE I am returning another function that will be used as a way to work with an internal c variable. The public function that is returned can be called from the outside to get and set the local c variable, but I can not directly work with it from the outside of the IIFE.
In this example I have an inner function that is returned to the public count variable. I can then call that function from the outside of the IIFE however I can not directly work with the private c variable. I can however work with the local c variable indirectly by way of the public method that is returned.
A function can be used as a public API but a plain old object can also be used as one also. Say I have a whole bunch of methods that I want to have as my public API for a game module. One way would be to attach them to a prototype object of a function, but what if they do not need to be part of a class of a constructor function? Also what if I do not want or need a constructor function at all, or a function of any kind as the public API? No problem just using a plain od object will work just fine.