1

我从 Stoyan Stefanov 的一本名为 Object Oriented JavaScript 的书的第 79 页得到了这个例子。真的不知道该做什么,我第一次运行这个程序(按回车键)它返回“未定义”。之后,按照作者的指示,我调用它a();并收到警报“Worky worky”

我的问题是

a) 我是否正确地完成了第一步?即我应该通过点击“进入/返回”来运行一个自调用程序吗?

b)如果我只是点击“进入/返回”来运行程序是正确的,为什么它会给出“未定义”的结果。作者说,这个程序拒绝引用(在第一次运行时)对函数 actualWork() 的引用?如果它返回一个引用,为什么它被认为是未定义的?它在某种程度上很重要吗?

请注意,我尝试在 jsfiddle.net 中输入代码,然后点击运行并没有发生任何事情,但是当我第一次在控制台中运行它时我得到“未定义”,然后当我执行 a(); 时出现警报。

var a = function() {
    function someSetup(){
        var setup = 'done';
    }
    function actualWork(){
        alert('Worky-worky');
    }
    someSetup();
    return actualWork;
}();
4

5 回答 5

4

这段代码相当于:

var f = function() {
    function someSetup(){
        var setup = 'done';
    }
    function actualWork(){
        alert('Worky-worky');
    }
    someSetup();
    return actualWork;
};

var a = f();

所以:您正在创建变量f并为其分配一个函数。然后,您将调用的结果分配f()a,这恰好也是一个函数(这在原始代码中隐式完成)。最后你可以运行a(),它运行返回的函数f()

于 2011-03-20T10:55:00.907 回答
4

“自调用”意味着这段代码在被编译器执行后立即生效,即使所有代码都在函数内部。发生这种情况是因为该函数被立即调用(()在最后一行)。

如果你只写这也是会发生的事情

function someSetup(){
    var setup = 'done';
}
function actualWork(){
    alert('Worky-worky');
}
someSetup();
return actualWork;

这里的区别在于“自调用程序”(恕我直言,这是一个错误的描述)允许您在不使名称someSetupactualWork调用代码可见的情况下执行此操作——这通常是可取的。

有了这个解释,让我们回答你的问题:

  1. 代码片段本身没有return任何作用(即使它分配给函数a返回的东西);因此您的 JS IDE 报告其返回值为.undefined
  2. 对函数的引用actualWork很好地返回(它是分配给 的值a);当您成功调用它时,您自己就看到了a()
于 2011-03-20T10:56:48.740 回答
2

a) 取决于您的解释器的工作方式,是的,只需运行脚本(按回车键)即可定义函数 a();

b)它给出了“未定义”,因为程序本身不返回任何东西,而是函数 a(); 做。您上面引用的代码代表一个函数 a(); 当被调用时,它应该执行以下操作:

  1. 定义 2 个其他(临时)函数
  2. 运行其中一个(someSetup)
  3. 返回另一个。

所以我会通过以下方式使用该程序:

  1. 运行以定义 a();
  2. 打电话var x=a();
  3. (可选)检查是否setup=='done'
  4. 调用x();(由 a() 返回)应该显示警报。

编辑 对不起,我没有看到 }(); 最后,所以它不是100%正确的。这 (); 最后是 - 正如 Jon 和 Tomasz 都所说 - “将函数的返回值作为新函数并立即运行”的缩写形式。

于 2011-03-20T10:53:49.880 回答
1

undefinded从正常的语句返回var a = ...。引用由赋值的右侧返回。

于 2011-03-20T10:51:38.513 回答
1

匿名函数被立即调用并返回对其中函数的引用actualWork。所以a包含这个引用并且可以被自己调用。所以a();应该给你警报。

于 2011-03-20T10:56:37.927 回答