JavaScript: Self-executing function with parameter
Asked Answered
F

2

5

CodeMirror.net uses this construct (I'm simplifying slightly) to introduce the code for its JavaScript editor:

(function(mod) {
        this.CodeMirror = mod();
    })(function() {
      "use strict";
       (15,000-odd lines of advanced JS)
    }

Now, I understand that this is a self-executing function, and I've read a number of posts about them. I understand that, in practice, this code is creating a CodeMirror object. I just don't understand the mechanics.

  1. What is the role of the parameter (mod)? More broadly, what does it mean when you give a parameter to a self-executing function?
  2. What is the role of the inner function() declaration? It appears that this is related to mod in some way?

Thanks for your help.

Ferreira answered 12/9, 2015 at 16:13 Comment(2)
The function is not self-executing. You are creating a function and then calling it immediately.Berlyn
Yes, the term "self-executing function" is colloquially out of favor. The preferred term is "immediately-invoked function expression", or IIFE.Visitant
V
5

In your code:

(function(mod) {
    this.CodeMirror = mod();
})(function() {
  "use strict";
   (15,000-odd lines of advanced JS)
}

mod is the formal parameter to the immediately-invoked function. It's as if the function were declared in a more straightforward way:

function something(mod) {
    this.CodeMirror = mod();
}

That function clearly expects that the mod parameter will be a reference to some other function, because the only thing it does is make a function call with it.

The immediately-invoked function is, in fact, called with a function as the value of the mod parameter: specifically, this one:

function() {
  "use strict";
   (15,000-odd lines of advanced JS)
}

That function does whatever it does, and (presumably) returns an object reference to be used as the global CodeMirror entry point.

Because the first function — the immediately-invoked one — is invoked without any explicit this value, it expects that this will be set to the value of the global context, or window in a browser. Personally I think it would be safer to do that explicitly:

(function(mod) {
    this.CodeMirror = mod();
}).call(this, function() {
  "use strict";
   (15,000-odd lines of advanced JS)
})

In the global lexical context, it is guaranteed that this will be a reference to the global context, "strict" mode or not. But if that outer immediately-invoked function is simply called, then this will be undefined in "strict" mode and the initialization would fail.

Visitant answered 12/9, 2015 at 16:19 Comment(4)
So, if I understand you, this would be equivalent to: window.CodeMirror = function() { blah blah blah} ...except that it's an immediately invoked function, which affects its scope.Ferreira
I mean, window.CodeMirror = function() {blah blah blah}; window.CodeMirror();Ferreira
@Ferreira no, it's like window.CodeMirror = function() { blah }(); - the function has to be called, and the result of calling the function (the return value) is what becomes window.CodeMirror.Visitant
Oh! I get it. I think. Because it says this.CodeMirror = mod(); rather than this.CodeMirror = mod; Trippy. JavaScript just twangs my synapses!Ferreira
B
2
(function(mod) {
  this.CodeMirror = mod();
})(function() {
    "use strict";
    //(15,000-odd lines of advanced JS)
})

Nothing weird or magical is happening here, Here is the flow of this:

  1. (function(mod) { this.CodeMirror = mod(); }) This declares an anonymous function and it accepts the parameter mod.
  2. Then the line this.CodeMirror = mod(); takes the mod and invoke it like a method, implying that programmer's expects mod to be a function. The RETURN value of that method is assigned to Window.CodeMirror object. Self invoking functions have their this set to Window Object.
  3. Parenthesis right after anonymous function declaration invoke it, and in those parenthesis a function is passed a parameter.

Summary: The Result of function that has 15000 lines of code is assigned to Window.CodeMirror

Boris answered 12/9, 2015 at 16:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.