【问题标题】:Unexpected sequence of IIFE execution意外的 IIFE 执行顺序
【发布时间】:2017-05-20 14:01:55
【问题描述】:

我有点自学 JS hack 并尝试更正式一点,因为我必须构建一个行为更好的 JS 应用程序,它是名称空间和更好的 JS 公民。我会很感激一些关于我在这里做错的指示。

这个想法是使用第一个闭包来构造一个命名空间,然后在第二个中我将一个“类”构造函数添加到命名空间对象。我在 sub 上调用了一个方法。

(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: (intermediate value)(intermediate value)(intermediate value)(...) is not a function", "文件名": "http://stacksnippets.net/js", “亚麻”:03, “科尔诺”:1 }

当我阅读这段代码时,我希望两个 IIFE 将按顺序执行,第一个使 ProjectX 栩栩如生,然后第二个向 ProjectX 添加另一个构造函数,该构造函数将返回一个 subObj。此外,如果第 16 行的 console.log((ProjectX.attr1) 未注释,则代码将按我的预期运行。这似乎表明 ProjectX 实体在我引用它之前并不“存在”。这与我对 IIFE 的理解是它们立即运行,而且无论如何,ProjectX 不是构造函数——它是一个全局变量。

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

【问题讨论】:

  • 您在第一个 IIFE 之后缺少一个分号,这在删除带有分号的 console.log 时变得相关。可以搜索JS中需要分号的情况。此外,您可以尝试将 es6 与 babel 一起使用,以更好地组织代码并具有更好的可读性。
  • 谢谢@sabithpocker。关于 ES6 我必须涵盖当前常见的浏览器,我相信 ES6 还没有完全涵盖。
  • 试试Babel
  • 如果你想更新你的技能,那么直接转到 ES6 模块,这样就不需要所有这些 IIFE 和滚动你自己的命名空间的废话了。
  • @VanquiishedWombat Babel 将 es6 代码转换为 es5,因此兼容性没有问题。您可以编写以 es6 组织的代码并部署转译的 es5 版本。一旦浏览器全部覆盖,您就可以按原样发布 es6 并跳过转译。

标签: javascript iife


【解决方案1】:

您在第一个 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 返回一个函数,而您的代码不是这种情况,因此它会抛出一个类型错误,说明它需要一个函数但未定义。您的代码最终评估为:

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

或更简化为

undefined(<a function as parameter>)()

然后抛出错误,即此处应为function 而不是undefined

阅读 javascript 中的高阶函数,以更好地了解此语法以及您的代码存在歧义的地方。

【讨论】:

  • 只是为了确认一下,JS 将其视为从右到左解析的 ()()()() 之类的东西?所以第一个 IIFE 在第二个之前没有被评估,此时 ProjectX 没有定义。正确吗?
  • 不,这不对,这与定义 ProjectX 无关。 myFunction()()() 的评估更像是从左到右而不是从右到左。我会尝试更新答案以包含更多详细信息。
猜你喜欢
  • 1970-01-01
  • 2016-03-05
  • 1970-01-01
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 2020-10-20
  • 2017-09-30
  • 1970-01-01
相关资源
最近更新 更多