全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

JavaScript利用闭包实现模块化

利用闭包的强大威力,但从表面上看,它们似乎与回调无关。下面一起来研究其中最强大的一个:模块。

function foo() {
 var something = "cool";
 var another = [1, 2, 3];
 function doSomething() {
 console.log( something );
 }
 function doAnother() {
 console.log( another.join( " ! " ) );
 }
}

正如在这段代码中所看到的,这里并没有明显的闭包,只有两个私有数据变量something和another,以及doSomething() 和doAnother() 两个内部函数,它们的词法作用域(而这就是闭包)也就是foo() 的内部作用域。

接下来考虑以下代码:

function CoolModule() {
 var something = "cool";
 var another = [1, 2, 3];
 function doSomething() {
 alert( something );
 }
 function doAnother() {
 alert( another.join( " ! " ) );
 }
 return {
 doSomething: doSomething,
 doAnother: doAnother
 };
}
var foo = CoolModule();
foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3

这个模式在JavaScript 中被称为模块。最常见的实现模块模式的方法通常被称为模块暴露,这里展示的是其变体。我们仔细研究一下这些代码。

首先,CoolModule() 只是一个函数,必须要通过调用它来创建一个模块实例。如果不执行外部函数,内部作用域和闭包都无法被创建。其次,CoolModule() 返回一个用对象字面量语法{ key: value, ... } 来表示的对象。这个返回的对象中含有对内部函数而不是内部数据变量的引用。我们保持内部数据变量是隐藏且私有的状态。可以将这个对象类型的返回值看作本质上是模块的公共API。这个对象类型的返回值最终被赋值给外部的变量foo,然后就可以通过它来访问API 中的属性方法,比如foo.doSomething()。

从模块中返回一个实际的对象并不是必须的,也可以直接返回一个内部函数。jQuery 就是一个很好的例子。jQuery 和$ 标识符就是jQuery 模块的公共API,但它们本身都是函数(由于函数也是对象,它们本身也可以拥有属性)。

doSomething() 和doAnother() 函数具有涵盖模块实例内部作用域的闭包( 通过调用CoolModule() 实现)。当通过返回一个含有属性引用的对象的方式来将函数传递到词法作用域外部时,我们已经创造了可以观察和实践闭包的条件。如果要更简单的描述,模块模式需要具备两个必要条件。

1. 必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。

2. 封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。

一个具有函数属性的对象本身并不是真正的模块。从方便观察的角度看,一个从函数调用所返回的,只有数据属性而没有闭包函数的对象并不是真正的模块。上一个示例代码中有一个叫作CoolModule() 的独立的模块创建器,可以被调用任意多次,每次调用都会创建一个新的模块实例。当只需要一个实例时,可以对这个模式进行简单的改进来实现单例模式:

var foo = (function CoolModule() {
 var something = "cool";
 var another = [1, 2, 3];
 function doSomething() {
 alert( something );
 }
 function doAnother() {
 alert( another.join( " ! " ) );
 }
 return {
 doSomething: doSomething,
 doAnother: doAnother
 };
})();
foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3

立即调用这个函数并将返回值直接赋值给单例的模块实例标识符foo。

模块也是普通的函数,因此可以接受参数:

function CoolModule(id) {
 function identify() {
 console.log( id );
 }
 return {
 identify: identify
 };
}
var foo1 = CoolModule( "foo 1" );
var foo2 = CoolModule( "foo 2" );
foo1.identify(); // "foo 1"
foo2.identify(); // "foo 2"

模块模式另一个简单但强大的变化用法是,命名将要作为公共API 返回的对象:

var foo = (function CoolModule(id) {
function change() {
 // 修改公共API
 publicAPI.identify = identify2;
}
function identify1() {
 alert( id );
}
function identify2() {
 alert( id.toUpperCase() );
}
var publicAPI = {
 change: change,
 identify: identify1
};
return publicAPI;
})( "foo module" );
foo.identify(); // foo module
foo.change();
foo.identify(); // FOO MODULE

通过在模块实例的内部保留对公共API 对象的内部引用,可以从内部对模块实例进行修改,包括添加或删除方法和属性,以及修改它们的值。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# js  # 闭包  # 模块化  # JS沙箱模式实例分析  # JavaScript 设计模式 安全沙箱模式  # JavaScript的模块化:封装(闭包)  # 继承(原型) 介绍  # JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)  # js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)  # JavaScript设计模式之观察者模式(发布者-订阅者模式)  # JavaScript 设计模式之组合模式解析  # javascript 设计模式之单体模式 面向对象学习基础  # javascript设计模式之解释器模式详解  # 常用的Javascript设计模式小结  # JavaScript设计模式之工厂方法模式介绍  # JS实现闭包中的沙箱模式示例  # 创建一个  # 返回值  # 被称为  # 它来  # 的是  # 都是  # 很好  # 域外  # 中有  # 这段  # 能在  # 可以通过  # 并将  # 可以直接  # 上看  # 必要条件  # 或删除  # 只需要  # 而这  # 来实现 


相关文章: 如何通过山东自助建站平台快速注册域名?  魔方云NAT建站如何实现端口转发?  建站主机如何安装配置?新手必看操作指南  如何选择香港主机高效搭建外贸独立站?  建站之星如何助力网站排名飙升?揭秘高效技巧  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  如何在阿里云虚拟服务器快速搭建网站?  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  如何在景安云服务器上绑定域名并配置虚拟主机?  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  如何选购建站域名与空间?自助平台全解析  网站制作哪家好,cc、.co、.cm哪个域名更适合做网站?  如何高效利用亚马逊云主机搭建企业网站?  建站之星会员如何解锁更多建站功能?  网站制作费用多少钱,一个网站的运营,需要哪些费用?  如何在香港免费服务器上快速搭建网站?  贸易公司网站制作流程,出口贸易网站设计怎么做?  西安大型网站制作公司,西安招聘网站最好的是哪个?  如何快速查询网站的真实建站时间?  如何在IIS7中新建站点?详细步骤解析  如何在Ubuntu系统下快速搭建WordPress个人网站?  制作宣传网站的软件,小红书可以宣传网站吗?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何选择高性价比服务器搭建个人网站?  小型网站制作HTML,*游戏网站怎么搭建?  建站主机无法访问?如何排查域名与服务器问题  ,如何利用word制作宣传手册?  建站主机服务器选型指南与性能优化方案解析  如何快速建站并高效导出源代码?  如何安全更换建站之星模板并保留数据?  建站之星24小时客服电话如何获取?  企业网站制作费用多少,企业网站空间一般需要多大,费用是多少?  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  TestNG的testng.xml配置文件怎么写  Java解压缩zip - 解压缩多个文件或文件夹实例  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  网站制作公司,橙子建站是合法的吗?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  娃派WAP自助建站:免费模板+移动优化,快速打造专业网站  宝塔新建站点为何无法访问?如何排查?  Thinkphp 中 distinct 的用法解析  如何快速上传建站程序避免常见错误?  网站图片在线制作软件,怎么在图片上做链接?  网站按钮制作软件,如何实现网页中按钮的自动点击?  建站之星安全性能如何?防护体系能否抵御黑客入侵?  用v-html解决Vue.js渲染中html标签不被解析的问题  公司网站制作价格怎么算,公司办个官网需要多少钱?  如何快速重置建站主机并恢复默认配置?  定制建站价位费用解析与套餐推荐全攻略  建站之星伪静态规则如何正确配置? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。