I have an application that in debug mode is written in many separate javascript files, but are loaded synchronously as part of the head block of a page. In release, I merge all these files together and minifiy them. Today I kept finding an error in the minified version, so I loaded up a single merged file to debug the issue and found that one library was self executing a function and it was causing other functions defined on window
to be executed.
I've repo'd the behavior here with a generic object, doesn't matter if its window or not:
<head>
<script>
var a = {}
a.X = function x(){
console.log("shouldn't be executed");
}
(function(a){
console.log("self execution");
}(a));
</script>
</head>
In this example, I get the output of
self execution
shouldn't be executed
If I change the call to be
<head>
<script>
var a = {}
function x(){
console.log("shouldn't be executed");
}
a.X = x;
(function(a){
console.log("self execution");
}(a));
</script>
</head>
Then I just get
self execution
Which is what I expected. In the first example, why is X
getting called when a
is passed to the self executing function?
A JavaScript function that runs as soon as it is defined. Also known as an IIFE (Immediately Invoked Function Expression).
A self-invoking (also called self-executing) function is a nameless (anonymous) function that is invoked immediately after its definition. An anonymous function is enclosed inside a set of parentheses followed by another set of parentheses () , which does the execution. (function(){ console. log(Math.
Self-Invoking Functions A self-invoking expression is invoked (started) automatically, without being called. Function expressions will execute automatically if the expression is followed by (). You cannot self-invoke a function declaration.
It is a design pattern which is also known as a Self-Executing Anonymous Function and contains two major parts: The first is the anonymous function with lexical scope enclosed within the Grouping Operator () . This prevents accessing variables within the IIFE idiom as well as polluting the global scope.
You are missing the ;
after you assign the function to a.X
.
Semi-colon insertion is not triggered.
The (
and )
around the anonymous function are used to call the previous function, and its return value is assigned to X
.
i.e. what you have is equivalent to:
var a = {};
a.X = (function x(){
console.log("shouldn't be executed");
}(
(function(a){
console.log("self execution");
}(a))
));
Incidentally, this issue is a good advert for JS Lint, which would have picked it up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With