This is true of the function itself, but there can be many traces (good and bad/accidental) that the function has run. The most accidental way is if you forget to declare a variable and use it. This will be detected as an error if you opt-in to ES5’s strict mode:
(function(){ 'use strict'; foo = 5 })() // Uncaught ReferenceError: foo is not defined
If you aren’t using strict mode, which is the default, you will have just set the global variable foo
in your program.
Plus, you can still mess with any global program state, even in strict mode, as long as those objects aren’t frozen:
(function(){ 'use strict'; Math.PIE = 3 })()
Math.PIE // 3
So, as the tutorial mentions, IIFEs are great for protecting the IIFE code from the rest of your (or others’) programs, but they don’t stop your IIFE code from wreaking havoc on the code outside of your IIFE.
There are ways other than using wrapping parentheses to reach a valid point in the grammar so that your function is treated as an expression. Pretty much any unary operator will work, for example:
void function(e){ console.log(e) }('hi')
!function(e){ console.log(e) }('hi')
typeof function(e){ console.log(e) }('hi')
I forget if there’s any good reason why people have settled on the paren syntax, other than that it reminds people of Lisp, I guess.
That’s a great point about IIFEs having the ability to wreck things outside of their bubbles. I’ll modify the tutorial by adding a note summarizing what you mention.
Regarding the syntax, the paren version does look at lot like Lisp haha!
Void… Cooool. Looks like the return type
Hello, please make sure that what you write about is actually true and tested.
I have tried running this code in multiple enviroments (browser console, jscomplete-com, jsfiddle-net and playcode-io) :
function quotatious(names) {
let quotes = [];
for (let i = 0; i < names.length; i++) {
let theFunction = function() {
return "My name is " + names[i] + "!";
}
quotes.push(theFunction);
}
return quotes;
}
// our list of names
let people = ["Tony Stark", "John Rambo", "James Bond", "Rick James"];
// getting an array of functions
let peopleFunctions = quotatious(people);
// get the first function
let person = peopleFunctions[0];
// execute the first function
alert(person());
And it runs just fine with “Tony Stark” being shown in the alert popup.
@richtone This is a consequence of updating the site’s code samples to use more modern JavaScript, namely switching over from var
to let
. There is, however, a difference of behavior between these two types of declarations, one of which breaks this example. So by blinding making that replacement, this example no longer shows the broken behavior. If you change the let
s to var
s, you should see what was reportedly to be expected (specifically for the for
).
@kirupa I want to think I remember this coming up for the book too, but I don’t remember what we did. Used var
in this case? Removed this example?
Apologies @richtone. As @senocular mentions, this is an oversight from me doing a find/replace of vars
into lets
. I’m going to revise this tutorial to go back to using var
with a note that none of this works when using let
.
@senocular - the entire chapter was