意外的IIFE执行顺序

时间:2017-05-20 14:01:55

标签: javascript iife

我是一个自学成才的JS黑客,并试图更正式,因为我必须建立一个更好的JS应用程序,名称间隔和更好的JS公民。我会很感激我在这里做错了一些指示。

这个想法是使用第一个闭包来构造一个命名空间,然后在第二个我添加一个方法a' class'构造函数到命名空间对象。我在子上调用了一个方法。



(function() {
    'use strict';
    /**
     * @namespace ProjectX
     */

    var ProjectX = {

        attr1: 'I am inside ProjectX'
        
    }
    window.ProjectX = ProjectX;

})()

//console.log(ProjectX.attr1); // When this line is uncommented the code will output 'foobar' as expected?

(function() {
    'use strict';

    ProjectX.subObj = function(val) {
        this.name = val;
        return this;
    };
})();


var subObj = new ProjectX.subObj('Foobar');
console.log(subObj.name);




我期待着看到Foobar'在控制台日志中。但是,这会在控制台中产生以下结果:

  

{     " message":" Uncaught TypeError :(中间值)(中间值)(中间值)(...)不是函数",     " filename":" http://stacksnippets.net/js",     " lineno":03,     " colno":1   }

当我读到这段代码时,我希望两个IIFE将按顺序执行,第一个将ProjectX带入生命,然后第二个向ProjectX添加一个将返回subObj的构造函数。此外,如果第16行的console.log((ProjectX.attr1)未被注释,代码将按照我的预期运行。这似乎表明ProjectX实体不会出现,直到我有这与我对IIFE的理解相矛盾,即它们立即运行,无论如何,ProjectX不是构造函数 - 它是一个全局变量。

在研究中,我发现function inside of IIFE not recognized似乎是相似的区域,但与将事件绑定到DOM而不是与我的查询并行相关。

1 个答案:

答案 0 :(得分:4)

在第一个IIFE之后你缺少一个分号,当删除带分号的console.log时,它就变得相关了。您可以搜索JS中需要分号的情况

没有分号,您的代码可以解释为:

(function() {
    var ProjectX = {
        attr1: 'I am inside ProjectX'
    }
    window.ProjectX = ProjectX;
})()(function() {
    ProjectX.subObj = function(val) {
        this.name = val;
        return this;
    };
})();

(IIFE)()()格式检查以下函数,这是有效的,因为IIFE返回一个函数,该函数使用('Hey')

调用

    (function() {
        return function(msg){console.log(msg)}
    })()('Hey')

没有分号,javascript期望你的第一个IIFE返回一个函数,这不是你的代码的情况所以它抛出一个Type错误,说它期待一个函数但是未定义。您的代码最终评估为:

undefined(function() {
    ProjectX.subObj = function(val) {
        this.name = val;
        return this;
    };
})();

或更简化为

undefined(<a function as parameter>)()

然后会抛出错误,即此处需要function而不是undefined

阅读javascript中的高阶函数,以便更好地了解这种语法以及代码模糊不清的内容。