模块模式-如何将一个模块的代码拆分到不同的js文件中?

2023-11-24

对于模块模式,我正在做类似的事情:

(function(namespace) {
    // tons of code
    // blabla
})(window.myGlobalNamespace);

如何拆分代码?我可以想到几种方法,例如使用命名空间的层次结构,或者通过以下方式将对象扩展到外部window.myGlobalNamespace.additionalFunc = function () {//blabla}。还有哪些其他方法?优缺点都有什么?哪一种被认为是更好的做法?

这两个答案都建议使用 RequireJS。您能否解释一下 RequireJS 如何解决这些问题:

首先.js:

(function(context) {
    var parentPrivate = 'parentPrivate';
})(window.myGlobalNamespace);

第二个.js:

(function(context) {
    this.childFunction = console.log('trying to access parent private field: ' + parentPriavte);
}(window.myGlobalNamespace.subNamspace);

main.js:

window.myGlobalNamespace.subNamspace.childFunction(); // doesn't work

人们可以做到

window.myGlobalNamespace.subNamspace.childFunction = function() {alert("a new function");}

改变我的代码的行为!

这里,有两个问题:

  1. 我们不能有一个儿童可以访问但外部公众不能访问的字段(即受保护的字段)。有什么办法可以实现这一点吗?

  2. 如果不是,这意味着如果我们希望可以访问parentPrivate,我们需要将其公开。然后用户就可以修改它了!

更重要的是,所有的公共职能都可以改变和替换。我不希望这种事发生。

我不明白 RequireJS 如何解决这些问题。有人可以透露一些信息吗?


将 JavaScript 转换为 HTML 只有两种方法:

  1. Inline - <script> some JavaScript </script>
  2. Link - <script src='main.js'></script>

我知道这是显而易见的,但我们需要为接下来的事情找到共同点。 ;)

JavaScript 没有能力将其他 JavaScript 文件“导入”到它自身中。所有“导入”都是在 HTML 中完成的。您可以通过多种方式执行此操作:

  • Link每一项都单独放入 HTML 中
  • 动态链接他们通过一些JavaScript

    var script = document.createElement("script");
    script.src = "all.js";
    document.documentElement.firstChild.appendChild(script);
    
  • Library like 要求JS。 RequireJS 使用异步模块定义 (AMD) API。它是用于定义模块的 JavaScript 机制,以便可以异步加载模块及其依赖项。

考虑将 JavaScript 分成单独文件的原因很重要。

  • 可维护性- 一次处理一件作品变得更加容易
  • 可读性- 如果所有内容都在一个大文件中,则很难看出什么是什么
  • 分工- 让多个开发人员处理多个文件比处理一个大文件更容易
  • Reuse- 您的所有功能都可以分解为高度凝聚力模块

单独的 JavaScript 文件DO NOT做东西Private,闭包使事情变得私有。

现在,考虑一下在一天结束时,当一切都准备好进行生产时,您能做的最好的事情是Optimize您可以将 JavaScript 全部合并到一个文件中,以便用户只需下载一个文件。


在 JavaScript 中处理私有变量时,您有时会想要访问它们。

  • Public功能 - 可以altered.
  • 特权函数-aPublic可以访问的函数Private多变的。
  • 但是,如果该函数位于Instance那么它就可以只能在每个对象中更改.

让我用一些代码来说明。

module-test.html 和 main.js (合并了first.js、second.js 和main.js 以方便测试)

var MODULE = (function () {
	//Private variables
	var privateParent,
	    app;
	
	privateParent = 'parentPrivate';
	
	return app = {
		//Privileged method
		getPrivateParent: function() {
			return privateParent;
		}
	};
}());

MODULE.sub = (function (parentApp) {
	//Private variables
	var childMessage,
	    Constr;
	
	childMessage = ' - trying to access parent private field: ' + parentApp.getPrivateParent();  //prints parentPrivate

	Constr = function () {
		this.childF = this.childFunction();
	};
	
	//Constructor
	Constr.prototype = {
		constructor: MODULE.sub,
		version: "1.0",
		childFunction: function () {
			$("#testing-div").append(childMessage + "</br>");
		}
	};
	return Constr;
	
}(MODULE));
	
//We could just as easily print to the console, but the 'append' allows us to display the results on the page.

$("#testing-div").append("This first part shows what <b>does not work</b>; everything is 'undefined'. " + "</br>");
$("#testing-div").append("You are unable to access the var or func directly. " + "</br>");
$("#testing-div").append("MODULE.privateParent = " + MODULE.privateParent + "</br>");
$("#testing-div").append("MODULE.app = " + MODULE.app + "</br>");
$("#testing-div").append("MODULE.sub.childMessage = " + MODULE.sub.childMessage + "</br>");
$("#testing-div").append("MODULE.sub.Constr = " + MODULE.sub.Constr + "</br>");
$("#testing-div").append("MODULE.sub.childFunction = " + MODULE.sub.childFunction + "</br>");
$("#testing-div").append("END lesson. You must access childFunction() through the <b>new</b> operator." + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
	
$("#testing-div").append("Let's see if making an instance of the Object works" + "</br>");
var test = new MODULE.sub();
test.childFunction(); //run the method
$("#testing-div").append("Looks like it did!!!!" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
	
$("#testing-div").append("Now let's try to change the childFunction() ?" + "</br>");
test.childFunction = function() {$("#testing-div").append(" - This is a new function." + "</br>");}
test.childFunction(); // altered version
$("#testing-div").append("Looks like it was changed. :(" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
$("#testing-div").append("Does it stay changed?" + "</br>");
var test2 = new MODULE.sub();
test2.childFunction(); // doesn't work
$("#testing-div").append("NO, it was only Overriden in the 'test' Object.  It did not effect all the other new objects. :)" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Module Test</title>
<!-- 	<script data-main="scripts/main" src="scripts/require.js"></script> -->
</head>
<body>
    <h1>This is a test for separate Modules and Private variables.</h1>
    <div id="testing-div">
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="main.js"></script>
</body>
</html>
---

如果您想使用 RequireJS 来完成上述任务,也可以。 RequireJS 使用你我已经在使用的模块模式。如果您想分离文件,有两种方法可以实现。

  1. Normal- 只需设置您的 JS 文件以使用 RequireJS,然后只需稍作修改即可放入上述模块。
  2. 杠杆化- 使用 RequireJS 的模块性质作为设置闭包的模块。这看起来可能更难弄清楚,但从长远来看可能更有效。

NOTE: 我还没有机会比较这两个选项,但为了完整起见,我想将它们包括在内。


您可能会发现以下参考资料很有帮助:

  • JavaScript 模块模式:深入
  • JavaScript 中的私有成员
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模块模式-如何将一个模块的代码拆分到不同的js文件中? 的相关文章

  • Ajax文件上传

    我想使用 Ajax 和 php 上传文件 我有一个表格
  • libxmljs 的替代品 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 目标 使用 Node js 访问网页 使用 xpath 语法操作 DOM 并打印新的 DOM libxm
  • Crypto-Js 库的 hmac-256 脚本返回函数结构而不是 Google Apps 脚本中的值,在外部工作正常吗?

    我正在设置一个谷歌电子表格项目来连接到我的 CryptoExchange API 但是当涉及到这个简单的 CryptoJs Hmac sha256 脚本时 它不起作用 它返回函数结构而不是值 而在外部它工作正常 看我的jsfiddle ht
  • 我可以动态创建/销毁 Vue 组件吗?

    因此 我正在创建一个相当复杂的 Vue 应用程序 它从后端 API 获取数据并将其显示在前端 具体取决于用户选择的过滤器 它的默认设置是立即显示所有内容 然后一旦用户选择过滤器 它就会拉出不具有这些属性的 卡片 组件 直到今天 一切都很顺利
  • React Native:不透明视图内的透明视图

    我想用不透明框架和透明中心显示相机的视图 就像图片中的一样 黑色部分是相机的视图 我正在寻找具有纯反应本机组件的解决方案 没有额外的库 例如https github com gilbox react native masked view h
  • 您可以将现有的 div 复制到模式对话框吗

    我有一个带有多个面板的仪表板来显示不同的信息 我希望能够添加一个按钮来以模式显示面板 我正在使用引导程序 我所能找到的只是已经编写的模态 我想复制作为面板的 div 标签的内容 然后将其显示在模型中 但我不确定如何进行 该面板的 html
  • 实现悬停信息框

    我有一个日历 当用户将鼠标悬停在单元格上时 会出现一个很大的信息框 其中包含该日期的详细信息 虽然当用户离开时使信息框消失 但我遇到了一些麻烦 我基本上想要它 这样当鼠标光标移出信息框隐藏的日历单元格时 它就会消失 但我遇到了麻烦 因为mo
  • 限制 Dropzone 仅上传特定类型的文件

    我正在使用 Dropzone 上传文件 这是我的代码 div div
  • html canvas动画卡顿

    谁能解释为什么提供的画布动画断断续续 我创建了一个测试存根来演示该问题 我在桌面上的 FF Chrome IE 以及 Android 上的 FF 和 Chrome 中看到了卡顿现象 口吃是由于垃圾收集造成的吗 似乎 raf 在每次调用时都会
  • setInterval() 在用户离开选项卡时暂停?

    javascript 中是否有任何方法的行为类似于 setInterval 并且当用户离开选项卡时停止并在用户再次进入选项卡时恢复 您可以使用以下方法创建自己的 API可见性API https developer mozilla org e
  • Firebase 身份验证在 iOS 登录时卡住,没有错误

    我已经使用电子邮件和密码设置了 firebase 身份验证登录的最基本实现 firebase auth signInWithEmailAndPassword email password then gt console log Logged
  • 如何在 javascript 中基于类型字符串创建新对象?

    如何基于变量类型字符串 包含对象名称 在 javascript 中创建新对象 现在我有 随着更多工具的出现 列表会变得更长 function getTool name switch name case SelectTool return n
  • 有没有办法伪造同步 XHR 请求?

    我正在使用 Emscripten 系统将一堆 C 代码移植到 Javascript C 代码有很多调用fopen这是一个同步 IO 调用 在 Emscripten 中 我们使用对本地资源的 XHR 请求来模拟这一点however 在 Fir
  • 将预编译的车把模板与 Marionette 结合使用

    我正在使用带有 requirejs 的 Marionette 并且我还想使用预编译的车把模板 这是如何运作的 这是我当前的设置 需要 main js requirejs config baseUrl paths text vendor ja
  • jQuery 悬停时滚动到 div 并返回到第一个元素

    我基本上有一个具有设定尺寸的 div 和overflow hidden 该 div 包含 7 个子 div 但一次只显示一个 我希望当它们各自的链接悬停时能够平滑地垂直滚动 但是 第一部分 div 没有链接 并且是没有悬停链接时的默认部分
  • Aurelia - 仅 HTML 自定义元素的内联定义

    我的 Aurelia 视图模型中有一个递归对象 如下所示 Class BottomlessPit Name string MorePits BottomlessPit null 因此 我想在 Aurelia 视图中使用递归模板 它只会在一个
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 如何:带有 onclick 的 div 位于另一个带有 onclick 的 div 中

    只是一个简单的问题 我遇到了 div 与 onclick javascript 之间的问题 当我点击内部 div 时 它应该只触发它的 onclick javascript 但外部 div 的 javascript 也会被触发 用户如何点击
  • AngularJS 在指令运行之前通过 AJAX 检索数据

    我正在使用 AngularUIuiMap http angular ui github com directives map实例化谷歌地图的指令 uiMap 指令非常适合处理硬编码数据 mapOptions and myMarkers 但是
  • 用javascript调用外部网页(跨域)

    我正在尝试使用以下网络服务来验证提要这个问题 https stackoverflow com questions 11996430 check if a url is a valid feed 但浏览器不允许我向另一台服务器发送 ajax

随机推荐

  • Rijndael 256 加密:Java 和 .NET 不匹配

    我需要将 Rijandael 加密的 powershell 脚本转换为 Java 这是源powershell代码 Reflection Assembly LoadWithPartialName System Security Add Typ
  • 您遵循个人软件流程吗?您的组织/团队是否遵循团队软件流程? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 了解更多信息 维基百科上的
  • 延迟回调直到脚本添加到文档中?

    如何让回调在脚本实际附加到文档之前不运行 function addScript filepath callback if filepath var fileref document createElement script fileref
  • Strapi - 限制用户仅获取与他相关的数据

    通常 登录用户会获取内容类型的所有条目 我创建了一个 片段 内容类型 id name content users lt lt gt gt snippets lt lt gt gt 表示 具有并属于许多 关系 我创建了一些测试用户并提出请求
  • 在 pyspark 列表中对不同数据帧列求和的正确方法是什么?

    我想对 Spark 数据框中的不同列求和 Code from pyspark sql import functions as F cols A p1 B p1 df spark createDataFrame 1 2 4 89 12 60
  • 如何使用 jQuery 动画更改背景图像?

    我想使用慢速动画更改背景图像 但它不起作用 body stop animate background url 1 jpg slow 语法有问题吗 您可以通过将图像不透明度淡化为 0 然后更改背景图像 最后再次淡化图像来获得类似的效果 这将需
  • 在 R 中强制字符向量编码从“未知”到“UTF-8”

    我有一个问题字符向量编码不一致 in R 我从中读取表格的文本文件已编码 通过Notepad in UTF 8 我尝试过UTF 8 without BOM 也 我想从这个文本文件中读取表格 然后将其转换data table set a ke
  • 如何在 C++ 中高效应用多项式而无需循环? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我想获得一些复杂函数的准确近似值 pow exp log log2 比 C 标准库中 cmath 提供的更快 为此 我想利用浮点编码方式并使用位操作获取指数和尾数 然后进行多项式
  • 将包含多个数字的字符串转换为整数

    我意识到这个问题过去可能已经被问过好几次了 但无论如何我都会继续 我有一个程序将从键盘输入中获取一串数字 数字将始终采用 66 33 9 的形式 本质上 每个数字都用空格分隔 并且用户输入将始终包含不同数量的数字 我知道如果每个用户输入的字
  • 在 Firefox 中将焦点设置为 iframe 主体/内容?

    我有一个 iram 它具有隐藏的可见性 我单击按钮 iframe 将可见 我想关注其正文 内容 因为现在我必须单击按钮 然后进入 iframe 所以只需单击两次 我想一键完成 但不知道如何在 Firefox 中聚焦 在资源管理器中就可以了
  • iOS7新更新V 7.1(11D167)不兼容Xcode 5进行开发

    我收到IOS7新版本V7 1的通知 我已经安装在我的 iPhone 4S 上 由于我是开发人员 所以在 Xcode 5 SDK 的开发模式下未检测到我的 iPhone 4S 当我在 Xcode 中打开管理器时 表明 此 iOS SDK 安装
  • 神秘的 Rails 错误几乎没有痕迹

    我们的一个爬虫遇到了一个奇怪的问题 有时它会抛出一个Rails FATAL某些请求出错 但跟踪非常有限 看起来像这样 2014 07 01 18 16 37 FATAL Rails ArgumentError invalid encodin
  • python 字典中长(str)键的效率

    我正在解析一些 xml 使用一些 python 3 4 代码 并希望检索节点中的文本及其 id 属性 例子 li Some text here li 我当前的代码仅围绕文本构建 我现在添加 id 但之前不需要 我正在循环浏览文本 句子列表
  • 为什么 Apache 在 XAMPP 安装中无法启动?

    我已经迈出了学习 PHP 的第一步 认为这将是朝着正确方向迈出的良好一步 不过 我需要一些有关安装 XAMPP 的帮助 我已经通过 Apache Friends 站点下载了该文件和所有内容 但是当我前往控制面板时 我收到了许多错误 这就是它
  • Python scapy 导入错误

    如果我在 python 源文件中包含以下行 from scapy all import 我收到这个错误 from scapy all import ImportError No module named all 这在 Console 和 I
  • 使用点路径键字符串访问 Ruby 哈希

    Rails I18n 库将 YAML 文件转换为可使用 t 函数通过点路径调用访问的数据结构 t one two three four 有谁知道如何使用 Ruby Hash 来做到这一点 或者只能直接通过 YAML 对象实现 只需在路径中的
  • MOV AX,CS 和 MOV DS,AX 的概念

    谁能解释一下这三个指令的功能吗 ORG 1000H MOV AX CS MOV DS AX 理论上我知道代码 数据和额外的段是什么 但是 它们在这个程序中是如何实现的 为什么整个段被移到另一个段中 MOV AX CS and MOV DS
  • 为什么识别 XOR 运算符的反向传播神经网络需要偏置神经元?

    我发布了一个question昨天关于我的 XOR 运算符的反向传播神经网络遇到的问题 我做了更多的工作 意识到这可能与没有偏置神经元有关 我的问题是 偏置神经元的一般作用是什么 它在识别 XOR 运算符的反向传播神经网络中的作用是什么 是否
  • nginx 上游代理的后备

    我在图像服务器集群前面有一个 nginx 实例 upstream img farm 1 server 10 0 1 1 server 10 0 1 2 server 10 0 1 3 server 10 0 1 4 etc location
  • 模块模式-如何将一个模块的代码拆分到不同的js文件中?

    对于模块模式 我正在做类似的事情 function namespace tons of code blabla window myGlobalNamespace 如何拆分代码 我可以想到几种方法 例如使用命名空间的层次结构 或者通过以下方式