为了清晰起见而编辑 - @ Qantas94Heavy - 我明白它是什么“说”或应该做什么,我不明白的是为什么&更重要的是 如何运作:
我正在阅读关于JS模块模式的高级教程,它给出了这个例子:
var MODULE = (function (my) {
// add capabilities...
return my;
}(MODULE || {}));
困扰我的事情(我需要你的帮助)是最后一句话:
(MODULE || {}));
我无法理解这背后的语法规则,这使得它成为可能。在搜索关键字,“JavaScript模块语法”和“模块模式短手”之后,我发现我仍然不太了解这背后的基础。
有人请解释或指出我正确的方向,以获得更深入的了解吗?
此致 gggi
答案 0 :(得分:7)
(function(){
})();
是一个自我调用的匿名函数。在您的情况下,它处理“我的”对象参数:它对“我的”执行某些操作然后将其返回。
在您的情况下,函数接收的“my”参数是“(MODULE || {})”。
&&和||运营商被称为短路运营商。 ||如果“MODULE”对象存在,则返回“MODULE”对象,否则,将创建一个空对象以在函数内部使用。该函数将对该对象执行任何操作,该对象将成为返回的“MODULE”对象。
它通过创建一个闭包来工作:只要MODULE存在(它不是垃圾收集),自动调用匿名函数及其在赋值时的状态也是如此。这使得添加的任何功能都是持久的。
答案 1 :(得分:3)
右侧称为立即功能。要了解它是如何工作的,让我们分解一下:
(...)()
我们可以按名称调用函数,即f()
。但是,我们可以将任何表达式解析为函数类型的变量,而不是函数名称。在我们的例子中,第一组括号仅包含一个表达式。第二组是函数调用操作符。最终,(f)()
完全等同于f()
第二步是在第一个括号内提供一个匿名函数。结果是:(function(){})()
。匿名函数完全是类型函数。这会导致在同一语句中创建,执行和丢弃该函数。
第二组括号是函数调用运算符,它可以接受其中的参数,在我们的例子MODULE || {}
中。此表达式表示:如果定义了MODULE
,则使用它,否则,创建一个新的空的。
该参数作为名为my
的参数传递给匿名函数,匿名函数返回,嗯,my
。这会导致匿名函数评估为my
并生效:(my)(MODULE || {})
。
效果为MODULE
是自包含的,并且不会导致与外部变量的名称冲突。同时,它可以访问外部变量。
我希望这清除它:)
答案 2 :(得分: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 || {}));
在这里,因为我们使用了export关键字,所以我们要说awesomeNewModule是函数中的exports,现在所有这些export {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 || {}));
来源:关于javascript中的Module Patterns基础的树屋研讨会要记住的重要事情之一是,如果awesomeNewModule已经存在,那么您应该确保awesomeNewModule中不存在以下所有键{foo:5,bar:10}以及以下方法:出口。你好火星,出口。再见 如果是这样,那么最后加载的文件将覆盖先前文件中命名为相同的任何方法或值。
由于这个原因,您不能在模块之间共享值,如果一个模块的任何方面都依赖于另一个方面,那么您就不能保证我们依赖于这些值,但是最终还是要编写模块或代码是将应用程序拆分为彼此不依赖的部分,这样,如果一个模块向应用程序引入严重错误,则不会影响代码的快速执行。 此外,还有多种保护卡的方法,可确保一个模块不会覆盖从另一个模块创建的模式或方法。