带有示例的 JavaScript module模式

IT技术 javascript module
2021-01-14 04:12:10

我找不到任何显示两个(或更多)不同module如何连接在一起工作的可访问示例。

所以,我想问一下是否有人有时间写一个例子来解释module如何协同工作。

5个回答

为了接近module化设计模式,您需要首先了解这些概念:

立即调用函数表达式 (IIFE):

(function() {
      // Your code goes here 
}());

您可以通过两种方式使用这些功能。1. 函数声明 2. 函数表达式。

这里使用函数表达式。

什么是命名空间?现在,如果我们将命名空间添加到上面的代码中,那么

var anoyn = (function() {
}());

JS 中的闭包是什么?

这意味着如果我们声明任何具有任何变量作用域/在另一个函数内的函数(在 JS 中我们可以在另一个函数内声明一个函数!)那么它将始终计算该函数作用域。这意味着将始终读取外部函数中的任何变量。它不会读取同名的全局变量(如果有)。这也是使用module化设计模式避免命名冲突的目的之一。

var scope = "I am global";
function whatismyscope() {
    var scope = "I am just a local";
    function func() {return scope;}
    return func;
}
whatismyscope()()

现在我们将应用我上面提到的这三个概念来定义我们的第一个module化设计模式:

var modularpattern = (function() {
    // your module code goes here
    var sum = 0 ;

    return {
        add:function() {
            sum = sum + 1;
            return sum;
        },
        reset:function() {
            return sum = 0;    
        }  
    }   
}());
alert(modularpattern.add());    // alerts: 1
alert(modularpattern.add());    // alerts: 2
alert(modularpattern.reset());  // alerts: 0

上面代码的jsfiddle。

目标是对外界隐藏可变的可访问性。

希望这可以帮助。祝你好运。

你的第一个例子(function() { /* Your code goes here */}());实际上是一个 IIFE(立即调用函数表达式),好吧,它是匿名的,因为它没有名字,所以你甚至可能想称它为 IIAFE(立即调用匿名函数表达式)在stackoverflow.com/questions/上查看更多关于 IIFE 的信息2421911/…
2021-03-18 04:12:10
命名 iife 会更好吗?出于语义目的和更好的堆栈跟踪?它会改变代码中的任何内容吗?
2021-03-22 04:12:10
你的第二个例子看起来像一个对象还是我不对?
2021-03-30 04:12:10
为什么使用了 return 语句?如果我们省略 return {} 那么 add 和 reset 函数将是公开的,我猜他们可以访问局部变量 sum ?我对吗?
2021-04-02 04:12:10
这并没有解决 OP 的问题。它是对module模式的描述,而不是多个module如何按照 OP 的需要协同工作的示例。
2021-04-06 04:12:10

我真的建议任何进入这个主题的人阅读 Addy Osmani 的免费书:

“学习 JavaScript 设计模式”。

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

当我开始编写更易于维护的 JavaScript 并且我仍然将其用作参考时,这本书极大地帮助了我。看看他不同的module模式实现,他很好地解释了它们。

我还建议阅读我关于“定义module模式”的文章,该文章未包含在 Addy Osmani 的书中:github.com/tfmontague/definitive-module-pattern
2021-03-16 04:12:10
Stoyan Stefanov 对“JavaScript 模式”的评论amazon.com/product-reviews/0596806752注意:这似乎比“学习 JavaScript 设计模式”中的要好得多
2021-03-23 04:12:10
斯托扬的书要全面得多。它不仅涵盖了高级模式,而且还更深入地讨论了其他 JS 最佳实践。
2021-03-25 04:12:10
这与 Stoyan Stefanov 的“JavaScript 模式”相比如何
2021-03-31 04:12:10
“学习 JavaScript 设计模式”的评论amazon.com/product-reviews/1449331815
2021-04-09 04:12:10

我想我会通过讨论如何将module组合到应用程序中来扩展上述答案。我在 doug crockford 的书中读到了这方面的内容,但作为 JavaScript 新手,这一切仍然有点神秘。

我来自 ac# 背景,所以添加了一些我觉得有用的术语。

html

您将拥有某种顶级 html 文件。将其视为您的项目文件会有所帮助。您添加到项目中的每个 javascript 文件都想参与其中,不幸的是,您没有获得对此的工具支持(我使用的是 IDEA)。

您需要使用脚本标记将文件添加到项目中,如下所示:

        <script type="text/javascript" src="app/native/MasterFile.js" /></script>
        <script type="text/javascript" src="app/native/SomeComponent.js" /></script>

似乎折叠标签会导致事情失败 - 虽然它看起来像 xml,但它确实有更疯狂的规则!

命名空间文件

主文件.js

myAppNamespace = {};

而已。这只是为我们的其余代码添加一个全局变量。您也可以在此处(或在它们自己的文件中)声明嵌套命名空间。

module

一些组件.js

myAppNamespace.messageCounter= (function(){

    var privateState = 0;

    var incrementCount = function () {
        privateState += 1;
    };

    return function (message) {
        incrementCount();
        //TODO something with the message! 
    }
})();

我们在这里所做的是将一个消息计数器函数分配给我们应用程序中的一个变量。这是一个函数,它返回一个我们立即执行的函数

概念

我认为将 SomeComponent 中的第一行视为您声明某些内容的命名空间会有所帮助。唯一需要注意的是,所有命名空间都需要首先出现在其他文件中——它们只是以我们的应用程序变量为根的对象。

我目前只采取了一些小步骤(我正在从 extjs 应用程序中重构一些普通的 javascript,以便我可以测试它)但是它看起来非常好,因为您可以定义小的功能单元同时避免“这个”的泥潭' .

您还可以使用这种风格来定义构造函数,方法是返回一个函数,该函数返回一个带有函数集合的对象,而不是立即调用它。

谢谢!非常有帮助
2021-03-16 04:12:10

在这里https://toddmotto.com/mastering-the-module-pattern您可以找到彻底解释的模式。我想补充一点,关于module化 JavaScript 的第二件事是如何在多个文件中构建代码。很多人可能会在这里建议您使用 AMD,但我可以根据经验说,由于大量 HTTP 请求,您最终会在某些时候页面响应缓慢。出路是按照 CommonJS 标准将 JavaScript module(每个文件一个)预编译为单个文件。在此处查看示例http://dsheiko.github.io/cjsc/

这是正确的,但是生成的优化文件需要加载程序库(只是用 r.js v2.1.14 重新检查了它),这通常很重要。一旦我们编译了代码,我们就不需要解析异步加载的依赖项,我们不需要这个库。考虑一下:我们将module包装到 AMD 中,这意味着异步。加载,然后将它们编译成一个文件(不再单独加载),但加载整个库以解决它们(现在是多余的)。对我来说,这听起来不是最佳方式。当我们不异步加载时,为什么要使用 AMD?
2021-03-20 04:12:10
与 RequireJS 相比,almond.js 为完成的生产代码提供了一个更小的权重加载器,但相对而言,不只发出单个 http 请求的性能优势远远超过将加载器代码添加到module的成本,因此虽然它不是最优化的,但它是规模要小得多。在我看来,这个问题应该被扭转——为什么在浏览器不是同步的情况下假设同步?我实际上认为 RequireJS 和 CommonJS 都应该有一个内置的Promise实现。
2021-03-23 04:12:10
我已经体验过 AMD 的以下好处: * 不仅可以加载 JavaScript 文件;* 路径别名;好吧,CommonJS Compiler 解决了这些问题——它将非 JavaScipt/JSON 依赖项加载为数据,并且可以提供构建配置(包括别名)。唯一的缺点是它需要建造。但是现在每个人都为 CSS 预处理器构建项目。所以它只是为 Grunt/Gulp 添加一个额外的任务......
2021-03-25 04:12:10
所有 AMD 实现还提供预编译到单个文件中。
2021-04-01 04:12:10
这两种格式都是 CommonJS Modules/2.0 的有效路径,并提供相同的可扩展性。对我来说 - 处理 CJS Modules/1.1(这就是我所说的 CommonJS)要容易得多,代码看起来更干净。
2021-04-07 04:12:10

你可以在这里找到module模式 JavaScript http://www.sga.su/module-pattern-javascript/