【问题标题】:Javascript self executing function "is not a function"Javascript自执行函数“不是函数”
【发布时间】:2011-08-30 18:14:19
【问题描述】:

我有:

var Init = (function() {
   my js goes here
})();

当页面加载时,我的 js 会正确执行。我也有:

$('form :checkbox').change(function() {
   Init();
});

但是萤火虫说 Init 不是一个函数。

【问题讨论】:

    标签: javascript iife


    【解决方案1】:

    这不是一个函数。

    (function() {
       ...
    })()
    

    评估匿名函数然后在这种情况下,评估结果显然不会返回函数对象 :-)

    考虑:

    f = (function() {
       return "not a function :("
    })()
    alert(f())
    

    f = (function() {
       return function () { return "Yay!" }
    })()
    alert(f())
    

    编码愉快:)


    这是一个函数,它会“执行一次”,然后“返回那个稍后执行”。 (请参阅 “你可以 [分配] 一个函数或调用它;你不能同时做这两个......”来自 Slaks 的回答。)但是,我不会这样做。 p>

    Init = (function () {
      function Init () {
        alert("whee!")
      }
      Init()
      return Init
    })()
    Init()
    

    这是 CD Sanchez 的另一种解决方案(更短/更简洁)(见评论),它利用了赋值计算为赋值的事实:

    var Init; (Init = function Init () {
      alert ("wee");
    })()
    

    【讨论】:

    • 最后两个 sn-ps 可以简化为:var Init; (Init = function () { alert ("wee"); })()
    • @CD Sanchez 非常好。我被嵌套函数“卡住”了,我完全跳过了这种方法。答案已更新以反映。
    • 我现在使用 var Init = (function() { return function() {...} })();它正在按我的意愿工作。现在这是否是正确的模式,我不知道。
    • 为什么不直接写function Init(){} Init();?它使意图更加清晰。
    • @Zecc 确实,我会这样做。让自己陷入这个问题。
    【解决方案2】:

    为了让Init 作为函数执行,自执行函数中的代码必须返回一个函数,这样做的唯一原因是如果您需要根据某些数据状态动态构造特定函数:

    var Init = (function() {
    
        // some code
    
        return function () {
            // some dynamic code dependent upon your previous code
        };
    
    }());
    

    【讨论】:

      【解决方案3】:

      Init 不是函数;这是调用函数的结果。

      您可以创建一个函数或调用它;你不能同时做这两件事。

      从技术上讲,您可以通过添加 return arguments.callee; 以从调用中返回函数来解决此问题。
      然而,这是一个愚蠢的想法。

      您可能不应该调用该函数;您需要了解您希望代码做什么。

      【讨论】:

      • you can't do both at once - 是的,你可以:(function Init(){ /*...*/ })();
      • @dev:错了。那是一个命名的表达式,而不是一个声明。 kangax.github.com/nfe/#named-expr
      • 我认为也许“你可以分配一个函数或调用它;你不能同时做这两个......”可能会更好地表达这一点。
      • 赋值是一个有效的表达式——它返回你赋给变量的对象的“值”。考虑到这一点,您可以将赋值表达式括在括号中,并使用函数调用语法在赋值后立即调用函数:var Init; (Init = function () { ... })(); 请注意(var Init = ...)() 无效,因为var 语句不是表达式。
      • @CD Sanchez:赋值运算符从右到左工作。该函数将首先被调用,然后将其返回值分配给Init。这就是问题中的问题。注释中的代码中不需要括号。
      【解决方案4】:

      快速的 尝试像这样替换

      var Init = function() {
         my js goes here
      });
      

      加载调用初始化

      【讨论】:

      • 我希望它是一个自执行函数,但也可以稍后调用它。
      【解决方案5】:

      你可以这样做,但你也可以这样做

      function Init(){...}(); 
      

      没有什么可以阻止您拥有一个命名的自执行函数。 如果您想避免使用名为 Init 的函数,您可以按照 CD Sanchez 的建议进行操作并在执行时分配它。

      ();最后让它自动执行。将函数括在括号中使其匿名。但您似乎不希望它是匿名的。

      【讨论】:

        【解决方案6】:

        你可以尝试这样声明:

        (function Init(){ 
            /*...*/ 
        })();
        

        但这会减少这个函数在它的主体中的使用

        另一种方法是将声明与执行分开:

        var Init = function(){
            /*...*/
            },
            initResult = (function(){ return Init(); })();
        

        【讨论】:

        • 错了。那是一个命名的表达式,而不是一个声明。它在函数之外是不可见的。 kangax.github.com/nfe/#named-expr
        • 无论如何,如果我错了,请纠正我,但我认为Init 不会使用它在封闭范围内定义。也许您的意思是:var Init; (Init = function () { ... })();?
        • 是的,抱歉,这是不对的。除了 IE 实现错误之外,Init 不会像 OP 想要的那样在封闭范围内可用。
        • @CD Sanchez:这实际上与问题中的代码存在相同的问题,除非您 返回来自Init 的函数。
        • @patrick dw:我不这么认为——它会将函数存储在Init 中,然后执行赋值表达式的结果(这将是function () {} 部分)。我过去曾使用过它,并且效果很好。不过,我并非万无一失 - 如果您发现我的推理有缺陷,请告诉我。
        猜你喜欢
        • 1970-01-01
        • 2018-08-11
        • 2016-04-11
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 2017-09-01
        • 2010-10-10
        相关资源
        最近更新 更多