JavaScript之模块化编程
来源:互联网 发布:甘肃省远程网络培训网 编辑:程序博客网 时间:2024/05/20 00:10
前言
模块是任何大型应用程序架构中不可缺少的一部分,模块可以使我们清晰地分离和组织项目中的代码单元。在项目开发中,通过移除依赖,松耦合可以使应用程序的可维护性更强。与其他传统编程语言不同,在当前JavaScript里,并没有提供原生的、有组织性的引入模块方式。本文就来探讨一下目前的常见几种模块化解决方案。
1.对象字面量表示法
对象字面量可以认为是包含一组键值对的对象,每一对键和值由冒号分隔。对象字面量不需要使用new运算符进行实例化,在对象的外部也可以给对象添加属性和方法。示例如下:
var myModule = { myProperty: "jeri", // 对象字面量可以包含属性和方法 // 例如,可以声明模块的配置对象 myConfig: { useCaching: true, language: "en" }, // 基本方法 myMethod1: function () { console.log("method1"); }, // 根据当前配置输出信息 myMethod2: function () { console.log("Caching is:" + '(this.myConfig.useCaching) ? "enabled" : "disabled"'); }, // 根据当前配置输出信息 myMethod3: function (newConfig) { if (typeof newConfig === "object") { this.myConfig = newConfig; console.log(this.myConfig.language); } }}
2.Module模式
Module模式最初定义在传统的软件工程中,为类提供私有和公有封装的方法。在JavaScript中,并不能可以直接声明类,但我们可以使用闭包来封装私有的属性和方法,进而模拟类的概念,在JavaScript中实现Module模式。通过这种方式,我们就使得一个单独的对象拥有公有/私有方法和变量,从而屏蔽来自全局作用域的特殊部分,也就大大降低了变量声明之间和函数声明之间冲突的可能性。
var myModule = (function () { // 私有变量 var privateVar = 0; // 私有函数 var privateFun = function (foo) { console.log(foo); }; return { // 私有变量 publicVar: "foo", // 公有函数 publicFun: function (arg) { // 修改私有变量 privateVar ++; // 传入bar调用私有方法 privateFun(arg); } };}) ();
如上所示,通过使用闭包我们封装了私有变量和方法,而只暴露了一个接口供其他部分调用。私有变量(privateVar)和方法(privateFun)被局限于模块的闭包之中,只有通过公有方法才能访问。该模式除了返回的是一个对象而不是一个函数之外,非常类似于一个立即调用函数表达式,我们可以为返回的对象添加新的属性和方法,这些新增的属性和方法对外部调用者来说都是可用的。
Module模式的这种JavaScript实现对于具有面向对象开发经验的人来说非常简洁,但其也有自身的缺点和劣势。
由于我们访问公有和私有成员的方式不同,当我们想改变可见性时,我们需要修改每一个曾经使用该成员的地方,并不利于维护和升级,耦合度并不理想。而且,在之后新添加的方法里,我们并不能访问以前声明的私有方法和变量,因为闭包只在创建时完成绑定。我们也无法为私有方法创建自动化单元测试,修正私有方法也是极其困难的,我们需要复写所有与私有方法交互的公有方法,bug修正时工作量会很大。另外,我们也不能轻易的扩展私有方法。
关于脚本加载器
要讨论 AMD 和 CommonJS 模块,我们必然会谈及一个显而易见的话题——脚本加载器。目前,脚本加载是为了让我们能在现今的各种应用中都能使用模块化的 JavaScript 这个目标而服务的。有很多加载器用于 AMD 和 CommonJS方式中的模块加载,比较出名的有RequireJS 和 curl.js。关于脚本加载器的使用方式和运行机制,大家可以自行了解一下。
3.AMD模块
AMD全称是Asynchronous Module Definition,即异步模块加载机制。它诞生于使用XHR+eval的Dojo开发经验,其整体目标是提供模块化的JavaScript解决方案,避免未来的任何解决方案受到过去解决方案缺点的影响。AMD模块格式本身就是对定义模块的建议,其模块和依赖都可以进行异步加载,而且具有高度的灵活性,清除了代码和模块之间可能惯有的紧耦合。
关于AMD有两个非常重要的概念,那就是用于模块定义的define方法和用于处理依赖加载的require方法。
作为一个规范,只需定义其语法API,而不关心其实现。define函数定义如下:
define( [module-name?] /*可选*/, [array-of-dependencies?] /*可选*/, [module-factory-or-object]);
其中:
module-name: 模块标识,可以省略。如果没有这个属性,则称为匿名模块。
array-of-dependencies: 所依赖的模块,可以省略。
module-factory-or-object: 模块的实现,或者一个JavaScript对象。
具体示例如下:
define( "myModule", ["foo", "bar"], // 模块定义函数,依赖(foo,bar)作为参数映射到函数上 function (foo, bar) { // 创建模块 var myModule = { myFun: function () { console.log("Jeri"); } } // 返回定义的模块 return myModule; });
require用于加载JavaScript文件或模块的代码,获取依赖。示例如下:
// foo,bar为外部模块,加载以后的输出作为回调函数的参数传入,以便访问requrie(["foo", "bar"], function (foo, bar) { // 其他代码 foo.doSomething();});
下面是一个动态加载依赖的示例:
define( function (requrie) { var isReady = false, foobar; requrie(["foo", "bar"], function (foo, bar) { isReady = true, foobar = foo() + bar(); }); // 返回定义的模块 return { isReady: isReady, foobar: foobar }; });
AMD模块可以使用插件,也就是说当我们加载依赖时,可以加载任意格式的文件。AMD对于如何完成灵活模块的定义提供了明确的建议,使用AMD编写模块化的JS代码,比现有的全局命名空间和
4.CommonJS模块
5.ES Harmony模块
6.Imports和Exports模块
7.模块加载器 API
- JavaScript之模块化编程
- JavaScript之模块化编程
- JavaScript之模块化编程
- JavaScript之模块化编程
- Javascript模块化编程之【模块的写法】
- JavaScript之模块化编程(一)
- JavaScript之模块化编程(二)
- javascript模块化编程III
- Javascript 模块化编程
- Javascript模块化编程
- Javascript模块化编程
- javascript模块化编程
- javascript模块化编程
- Javascript模块化编程
- JavaScript 模块化编程 一
- Javascript 模块化编程
- Javascript模块化编程
- javascript模块化编程学习
- transmission-daemon已完成列表位置
- ubuntu上安装搜狗拼音输入法
- RecyclerView系列之(3):添加下拉刷新和上拉加载更多
- Android:DropPopMenu — 显示位置跟随操作按钮显示的带箭头的弹出菜单
- MVC, MVP, MVVM比较以及区别
- JavaScript之模块化编程
- Spring容器启动之后进行初始化操作
- linux进程间通信的几种机制的比较及适用场合
- linux 常用命令笔记
- ubuntu14.04安装搜狗
- JTable的常见用法
- 冰糖炖蛋
- 关于隐藏用户名 后几位隐藏证件后几位登录
- SpringCloud 简介