8

为清楚起见进行编辑- @Qantas94Heavy - 我明白它在“说”或应该做什么,我不明白的是为什么以及更重要的是它是如何工作的:

我正在阅读关于 JS 模块模式的高级教程,它给出了这个例子:

var MODULE = (function (my) {
// add capabilities...

return my;
}(MODULE || {}));

困扰我的事情(我需要你的帮助)是最后一句话:

(MODULE || {}));

我无法理解使其成为可能的语法规则。在搜索了一些关键字、“JavaScript Module Syntax”和“Module Pattern Short Hand”之后,我发现我仍然不太了解这背后的基础。

有人可以解释一下或指出我正确的方向来理解这个/获得更深入的理解吗?

真诚的,gggi

4

3 回答 3

7
(function(){

})();

是一个自调用匿名函数。在您的情况下,它处理“我的”对象参数:它对“我的”做一些事情,然后将其返回。

在您的情况下,函数接收的“my”参数是“(MODULE || {})”。

&& 和 || 运算符称为短路运算符。|| 如果“MODULE”对象存在,则返回“MODULE”对象,否则,将创建一个空对象以在函数内部使用。该函数将对该对象执行任何操作,该对象将成为返回的“模块”对象。

它通过创建一个闭包来工作:只要 MODULE 存在(它不是垃圾收集的),自调用匿名函数及其在赋值时的状态也是如此。这使得添加的任何功能都是持久的。

于 2013-08-24T17:36:12.177 回答
3

右侧称为立即函数。为了理解它是如何工作的,让我们把它分解一下:

  1. (...)()我们可以按名称调用函数,即f(). 但是,我们可以放置任何解析为函数类型变量的表达式,而不是函数名称。在我们的例子中,第一组括号仅仅包含一个表达式。第二组是函数调用运算符。最终,(f)()完全等价于f()

  2. 第二步是在第一个括号集中提供一个匿名函数。结果是:(function(){})()。匿名函数完全属于函数类型。这会导致函数在同一个语句中被创建、执行和丢弃。

  3. 第二组括号是函数调用运算符,可以接受其中的参数,在我们的例子中是MODULE || {}. 这个表达式的意思是:如果MODULE定义了,就使用它,否则,创建一个新的空的。

  4. 参数作为被调用的参数传递给匿名函数,my匿名函数返回 um, my。这会导致匿名函数评估为my并生效:(my)(MODULE || {}).

  5. 效果是MODULE自包含的,不会导致名称与外部变量发生冲突。同时,它可以访问外部变量。

我希望这可以清除它:)

于 2013-08-24T18:11:36.733 回答
0

很少,特别是对于大型项目,我们会将所有代码放在一个文件中,起初很容易将您的代码放在不同的文件中并按特定顺序将它们组合在一起,但这很快就会变得难以管理,使用称为的未知模式“失去增强”我们实际上可以利用 javascript 异步运行时环境。

为了实现这个模式,我们需要一小段逻辑。我们会说如果 awesomeNewModule 存在,然后导入它,否则 awesomeNewModule 只是新对象:

    var awesomeNewModule = (function(){
        var exports={
            foo:5,
            bar:10
        };
        exports.helloMars = function(){
            console.log("Hello Mars!");
        };
        exports.goodbye = function(){
            console.log("Goodbye!");
        }
        return exports;
    }(awesomeNewModule || {}));

因为我们使用了exports关键字,所以我们会说awesomeNewModule是一个函数中的exports,现在exports {foo:5, bar:10}的所有这些值将被分配给空对象{},如果这是第一个文件,或者如果在创建模块后加载此文件,则将被分配并扩展 awesomeNewModule。

var awesomeNewModule = (function(exports){
    var exports={
        foo:5,
        bar:10
    };
    exports.helloMars = function(){
        console.log("Hello Mars!");
    };
    exports.goodbye = function(){
        console.log("Goodbye!");
    }
    return exports;
}(awesomeNewModule || {}));

要记住的重要一件事是,如果 awesomeNewModule 已经存在,那么您应该确保这些键 {foo:5, bar:10} 都不存在于 awesomeNewModule 中,并且这些方法都不存在:exports.helloMars ,exports.goodbye 如果是这样,最后加载的任何文件都将覆盖以前文件中名称相同的任何方法或值。

出于这个原因,你不能在模块之间共享值,如果一个模块的任何方面依赖于另一个模块,那么你不能保证我们依赖这些值,但归根结底,编写模块或代码的重点是您将应用程序拆分为彼此不依赖的部分,这样如果一个模块向应用程序引入了中断错误,则不会影响代码的匆忙。此外,还有一些方法可以保护卡片,以确保一个模块不会覆盖从另一个模块创建的模式或方法。

来源:关于 javascript 中模块模式基础知识的树屋研讨会
于 2020-03-27T19:55:39.140 回答