JavaScript:带参数的自执行函数

5
CodeMirror.net使用这个结构(稍微简化了一下)来引入其JavaScript编辑器的代码:
(function(mod) {
        this.CodeMirror = mod();
    })(function() {
      "use strict";
       (15,000-odd lines of advanced JS)
    }

现在,我理解这是一个自执行函数,并且我已经阅读了很多相关的帖子。实际上,我知道这段代码创建了一个CodeMirror对象,但我不明白其中的机制。

  1. 参数(mod)的作用是什么?更广义地说,当你给自执行函数传递参数时意味着什么?
  2. 内部function()声明的作用是什么?它似乎与mod有关?

感谢您的帮助。


1
该函数不是自执行的。您正在创建一个函数,然后立即调用它。 - MinusFour
1
是的,“self-executing function”这个术语在口语中已经不太常用了。更常用的术语是“立即调用函数表达式”,或者称为IIFE。 - Pointy
2个回答

5

在你的代码中:

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

mod是立即调用函数的形式参数。这就好像该函数以更简单的方式声明:

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

这个函数明显期望mod参数是对另一个函数的引用,因为它唯一要做的就是使用它进行函数调用。

实际上,立即调用的函数确实使用函数作为mod参数的值:具体来说,就是这个函数:

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

这个函数执行它该做的事情,并(可能)返回一个对象引用作为全局 CodeMirror 的入口点。

由于第一个函数 - 即立即调用的函数 - 在没有任何显式 this 值的情况下被调用,因此它期望 this 将被设置为全局上下文的值,或者在浏览器中为 window。个人认为显式地设置更安全:

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

在全局词法上下文中,无论是否处于“严格”模式,保证this是全局上下文的引用。但是如果外部的立即调用函数仅仅被调用而不是作为构造函数使用,那么在“严格”模式下this将会是undefined,初始化过程将会失败。

所以,如果我理解你的意思,这将等同于:window.CodeMirror = function() { 呃呃呃 }……除了它是一个立即调用的函数,影响它的作用域。 - AngularNewbie
我的意思是,window.CodeMirror = function() {blah blah blah}; window.CodeMirror(); - AngularNewbie
@AngularNewbie 不是的,它就像 window.CodeMirror = function() { blah }(); - 函数必须被调用,并且调用函数的结果(返回值)就成为了 window.CodeMirror - Pointy
哦!我明白了。我想是因为它写的是this.CodeMirror = mod();而不是this.CodeMirror = mod;。这很神奇。JavaScript真是让我的神经元兴奋! - AngularNewbie

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

这里没有奇怪或神奇的事情发生,以下是它的流程:

  1. (function(mod) { this.CodeMirror = mod(); }) 这声明了一个匿名函数,并接受参数 mod
  2. 然后,this.CodeMirror = mod(); 这行代码获取 mod 并像调用方法一样调用它,说明程序员期望 mod 是一个函数。该方法的返回值被分配给 window.CodeMirror 对象。自执行函数的 this 被设置为 window 对象。
  3. 在匿名函数声明之后的括号中调用它,并向其中传递一个参数。

总结: 15000行代码的函数的结果被赋值给 window.CodeMirror


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接