Speaker 1: Let's talk about some useful usages of functions and scopes. Remember we talked about function expressions, that's where the function keyword is not in a declaration position. So here you see, I did my bad practice of doing an anonymous function. But on line three, I have a function expression, from line three to a.
And then I've done this weird thing of wrapping it in parentheses. We'll explain that in a moment. But why am I doing that? Well the reason, the reasoning behind it that's obvious from this code is, I've got a piece of code like lines five and six that I want to wrap, I want to hide in a new scope.
That would have worked, but the problem with that is that I would have leaked out a name. The name bob would have leaked out into the enclosing scope. That defeats the purpose of what I'm attempting to do. I'm attempting to hide some stuff not to pollute my existing scope.
So the way we can do this is what's called the iffy pattern. We can make this function expression, the one that starts on line three and then goes to here. We wrap it in parentheses to make it an expression. Remember if that parentheses was not there, would the function keyword be an expression or a declaration?
Be a declaration. That's not what we want. We want an expression, so one of the syntactic ways we make an expression is to just not make it the first word, first thing in the statement, by wrapping it in some parentheses. Now we need to execute that function right away, so we put another set of parentheses on the end of it and that immediately executes our expression.
So it can be anonymous or it could have been a named function expression, it would have been better if I'd have called it function IIFE, given it a name so that I don't have the same problems that I have with anonymous functions. But in any case when I say var foo it's now going to attach it to that local function scope, rather than polluting this outer scope.
So inside of here on line six the foo is foo2, but on line ten the foo is still just foo. Is everybody following that? Reminder, these little icons down on the bottom left are your clue that you should click on it and try it yourself, not just trust me.
He's created more J query plugins himself than I think the rest of the J query community combined. This guy is extremely prolific, super smart, he's a trainer for Boku out in Boston. Really smart guy. But he said, you know what, we need a name for this pattern. So he wrote a blog post kind of suggesting that we give it a name and the name that he suggested was immediately invoked function expression.
Well it's a function expression that gets immediately invoked. So it's an awfully good name for it and we shorten that to IIFE and that's now become sort of the defacto standard name for this pattern, is the IIFE pattern. It does not have to be stand alone like this.
These things can exist as part of assignments, as part is passing. But the key hallmark of an IIFE is that you have a function expression, either named or anonymous, that immediately invokes itself, and that's that open, close, parentheses on the end. So the IIFE pattern is really popular, I'd recommend go reading his blog post about it but that's what everyone calls it.
This is extremely important because many of us have in our own code right now, we have a big file with a whole bunch of code strewn all about the code, and the problem with that is that this stuff is strewn all over the place and we don't have any way to kind of protect stuff from being in the global name space and collisions and all that.
The most common solution to that is to put an IIFE statement at the top to start an IIFE, and put a closing IIFE like line eight at the bottom of your file and now automatically everything in that file is hidden inside of the IIFE scope. So let's say you've got 100 functions there and only one of those functions is actually necessary to be global.
We go and wrap an IIFE around it and now all 100 of them are private, and then you take one of those and you add it as a property to the window object or whatever to make it global. But you hide 99 of them from being public that didn't need to be public.
So as a little piece of homework, if you've got any spaghetti code where you got a whole bunch of stuff in the global, go home and wrap an IIFE around it and make your code better. Will, was there a question?
Speaker 2: Yes, there was a question in chat.
How would the IIFE pattern sound in our anthropomorphic compiler style conversation?
Speaker 1: That's a great question. So it's not a declared function. Obviously it was a function expression that got compiled, but it's not a declared function. So basically what the compiler would say, I mean not the compiler but the runtime would say, is, I have a function expression, it's an immediate value, kind of like the immediate quote foo is an immediate value.
It's an immediate value, so we reference that immediate value inside of our parentheses. As opposed to having a reference identifier that we needed to do a scope lookup of, this is an immediate value, just like 42 or quote foo. We have the immediate value and then we can immediately execute it with line eight.
So it's more akin to those immediate values on the right hand side than it is to some sort of lexical identifier.
Speaker 3: So it cuts out the run time.
Speaker 1: What's that?
Speaker 1: That's at run time, it was compiled ahead of time, obviously, it has to be compiled ahead of time.
From a run time perspective, it's not going to get executed until it gets to line three.
Speaker 1: Okay? Great question.
Speaker 4: Would you recommend naming the IIFE?
Speaker 1: I do recommend naming the IIFE.
Speaker 4: Like if you have-
Speaker 1: Very non-idiomatic, but I recommend always naming your IIFEs. Just name it IIFE.
But, in your stack traces you don't want to have anonymous functions anywhere, so give your IIFEs names as well. Okay. Now what are some variations on the IIFE pattern that are really useful? The first is that an IIFE is just a function call, which means we can pass things into it.
This is the call site of our function. We can pass values and variables into it, and we can name those parameters and they don't have to be the same thing. So I say foo bar here just to be kind of generic, but the most common way that this is done, what I do in my code, is I pass in the window object, but I call it global.
Now why do I do that? Inside of my IIFE I've got a hundred functions that are private, and I've got two or three functions that I need to make global. So inside of my function I've got 97 of them just a regular function declarations, and variables, and all kinds of, and those are all automatically private, it's obvious they're private.
But anywhere where I say global dot in front of something, it's obvious to me that I'm creating a global. So as a stylistic choice, rather than the window, which is a little less obvious, I give an alias, if you will, to my window object. I call it global.
And that's really obvious in my code, which things are global and not. That's one way of using it. That's what I like to do. Another extremely common example of this in the jQuery world is you're worried about making sure that the dollar sign really does legitimately point to the jQuery object, because there can be other frameworks that sort of can collide with that.
So what you do there on line eight instead of passing in that foo you pass in the named jQuery, the j capital Q, jQuery object. But you'd call it, on line three, you'd call it dollar sign. That way you know inside of your IIFE you're guaranteed that the dollar sign points to the jQuery that you wanted it to point to.
And many people will do a mixture of both of those. They'll make the window and the jQuery pass through multiple ones, but the IIFE pattern gives us a way to manually pass in an alias variable from the enclosing scope. Questions about IIFE?
Speaker 5: I've seen the pass undefined.
Speaker 5: As a second argument-
Speaker 1: Yeah.
Speaker 5: Is that for security or what?
Speaker 1: I don't actually like this practice. There's some people that were concerned about the fact that in non-strict mode, the undefined keyword was a writeable property. They were concerned that somebody may, on purpose or on accident, say, undefined equals true.
And then anywhere in your code where you were referencing the undefined, you'd get something you didn't expect. So the way they solve that, and the same way with the jQuery, they don't pass anything for the second parameter, but the named parameter on line three, they call it undefined, so they make sure that the undefined really is in fact undefined.
I think that's overkill. I don't think it's a really good pattern to recommend and it's fixed as a strict mode so it's not an issue anymore, but there are people that do that.