全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。
Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用。Douglas叫它模块模式(module pattern)。它是如下工作的:
- 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法:
YAHOO.namespace("myProject");
这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆盖)。现在我们可以开始添加YAHOO.myProject的成员。 - 对你的命名空间对象分配一个匿名函数返回值:
YAHOO.myProject.myModule = function () { return { myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty被访问。"; myPublicMethod: function () { YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod被访问。"); } }; }(); // 这个括号导致匿名函数被执行且返回
注意有闭合大括号和紧接着的括号()的最后一行—这种符号导致了匿名函数的立即执行,返回包含myPublicProperty和myPublicMethod的对象。只要这个匿名函数一返回,返回对象就作为YAHOO.myProject.myModule被访问。
- 在匿名函数中,在返回语句前加入“私有”方法和变量。到目前为止,我们只是将myPublicProperty和myPublicMethod直 接分配到YAHOO.myProject.myModule中。此外,当我们在返回语句之前放置一些代码时,这个模式还支持被增加的效用。
YAHOO.myProject.myModule = function () { //“私有”变量: var myPrivateVar = "我仅能在YAHOO.myProject.myModule内被访问。"; //私有方法: var myPrivateMethod = function () { YAHOO.log("我仅能在YAHOO.myProject.myModule内被访问。"); } return { myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty能被访问。" myPublicMethod: function () { YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod能被访问。"); //在myProject,我能访问私有的变量和方法 YAHOO.log(myPrivateVar); YAHOO.log(myPrivateMethod()); //myPublicMethod的原生作用域是myProject,我们可以用“this”来访问公共成员。 YAHOO.log(this.myPublicProperty); } }; }();
在上面的代码中,我们从一个匿名函数返回有两个成员的一个对象。在YAHOO.myProject.myModule内部,可以分别用 this.myPublicProperty和this.myPublicMethod来访问。在YAHOO.myProject.myModule外 部,公共成员可以用YAHOO.myProject.myModule.myPublicProperty和 YAHOO.myProject.myModule.myPublicMethod来访问。
私有变量myPrivateProperty和 myPrivateMethod只能被匿名函数本身或返回对象的成员访问。尽管匿名函数会立即执行和终止,但它们依然是保留着,凭借闭包 (closure)的力量——通过一个函数的局部变量在这个函数返回后是保留的规则。只要 YAHOO.myProject.myModule需要它们,我们的两个私有变量就不会被销毁。 - 实践这个模式。让我们来看看这个模式的一个常见应用案例。假设你有一个列表,列表上的一些项可以被拖拽。应用拖拽的项上有拖拽的CSS类。
<!--这个脚本文件包含所有的YUI实用程序--> <script type="text/javascript" src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script> <ul id="myList"> <li class="draggable">一项</li> <li>二项</li> <!--二项将不能被拖拽--> <li class="draggable">三项</li> </ul> <script> YAHOO.namespace("myProject"); YAHOO.myProject.myModule = function () { //YUI实用程序的私有简写引用: var yue = YAHOO.util.Event, yud = YAHOO.util.Dom; //私有方法 var getListItems = function () { // 注意这个地方使用其他的私有变量,包括"yud"YAHOO.util.Dom的简写: var elList = yud.get("myList"); var aListItems = yud.getElementsByClassName( "draggable", //得到仅有CSS类"draggable"的项 "li", //仅返回列表项 elList //限定搜索改元素的子 ); return aListItems; }; //这个放回的对象将变成YAHOO.myProject.myModule: return { aDragObjects: [], //可对外访问的,存储DD对象 init: function () { //直到DOM完全加载好,才实现列表项可拖拽: yue.onDOMReady(this.makeLIsDraggable, this, true); }, makeLIsDraggable: function () { var aListItems = getListItems(); //我们可以拖拽的那些元素 for (var i=0, j=aListItems.length; i<j; i++) { this.aDragObjects.push(new YAHOO.util.DD(aListItems[i])); } } }; }(); //上面的代码已经执行,所以我们能立即访问init方法: YAHOO.myProject.myModule.init(); </script>
这是一个简单的例子,特意写的详细一些——如果按照这种方式做,我们无疑能把它写的更紧凑。当项目变得更加复杂和它的API增加,这个模式缩放的很好。通过这种方式,它避免了全局命名空间,提供了对外的可以访问的API方法,支持受保护或“私有”的数据和方法。
- [1]原文:《a javascript module pattern》。这是在YUI blog上的,有的地方可能打不开,可以搜一下英文的转载或者利用搜索引擎的缓存也能看。
- [2]《A JavaScript Module Pattern – JavaScript的一种模组模式》这是别人的翻译,参考了不少,不过感觉挺不方便看的,这是我翻译的这篇文章的一个原因,当然最主要的原因是这篇文章算是学习YUI的最基础的文章了,整个YUI的模块模式都基于此。
相关推荐
JavaScript模块模式 然后,Node.js模块系统允许模块导出任何值,无论是字符串,数字,单个函数还是更复杂的对象。... 使用此模式,您可以创建几种模块模式:单例,基于闭包的类,基于原型的类和外观。
为了让每一章中的示例都尽可能地贴近实际应用,书中同时列举了一些JavaScript程序员最常见的任务,然后运用设计模式使其解决方案变得更模块化、更高效并且更易维护,其中较为理论化的例子则用于阐明某些要点。...
模块化编程是一种非常常见Javascript编程模式。它一般来说可以使得代码更易于理解,但是有许多优秀的实践还没有广为人知。 基础 我们首先简单地概述一下,自从三年前Eric Miraglia(YUI的开发者)第一次发表博客...
仅使用JSON模式将JavaScript对象从一种形式映射到另一种形式的节点模块。 (现在支持打字稿) 版本3.x不向后兼容,所有更改都在部分中。 四个主要功能是: 删除未定义的值是使JSON输出看起来更干净的一种选择 ...
Ext-To-MimeType模式ExtToMime是一个JavaScript模块,为您提供一种将文件扩展名映射到MimeType / CodeMirror模式的简便方法。 您可以为模块提供不带点的文件扩展名,然后将返回CodeMirror模式。要求该模块需要满足...
模块是’javascript’的一种设计模式,它为函数定义一个包装函数,并且该包装函数的返回值与模块的API保持一致: function createModule() { function hello(name) { console.log(name + '帅哥你好!'); } ...
ninjs包括一个基于模块模式( )和“ JavaScript:The Good Parts”( )的小型JavaScript框架基础) “ ninjs”命令行应用程序减轻了重复性任务(如编译,脚手架和更新应用程序)的痛苦。 ninjs用Ruby( )编写,...
1.2连接字符串和另一种数据类型 1.3条件比较字符串 1.4在字符串中查找子字符串 1.5从一个字符串提取子字符串 1.6检查一个存在的、非空的字符串 1.7将一个关键字字符串分解为单独的关键字 1.8插入特殊...
为了让每一章中的示例都尽可能地贴近实际应用,书中同时列举了一些JavaScript 程序员最常见的任务,然后运用设计模式使其解决方案变得更模块化、更高效并且更易维护,其中较为理论化的例子则用于阐明某些要点。
jmd.js 是极小型、高性能 Javascript 模块化管理库(浏览器端)。特点遵循规范,可以像Node.js 一样来写模块代码(参见:AMD、CMD)完全异步,不对源码做任何改动、没eval、setTimeout,全速加载!干干净净,只有一个...
它提供了一种编写作用域模块的简单方法,这些模块可以在文档就绪时触发,甚至在重要的 DOM 更改事件期间(例如在对话框或模式窗口中通过 AJAX 加载视图)期间重新触发。依赖关系用法该库管理 JavaScript 模块,允许...
Vuet是Vue.js的一种状态管理模式,它以模块化管理为核心,以规则更新为主,手动更新为辅来进行模块的状态更新,总之它给你提供了一片草原,由你来决定如何驰骋
只获取数据的模块只能进行模板内部调用,其他类模板代码可以进行两种模式的调用显示:模板内部调用、JavaScript 调用。数据会自动缓存并按指定的时间间隔进行周期更新。 通过创建不同的模块代码,并放置于模板中加以...
Javascript 修订模块 redact 遍历 javascript 对象并替换或删除值。 编辑是就地完成的,但为方便起见,返回输入的引用。 编校规范(“spec”)是一个字段模型对数组(单个名称:值映射数组)。 不同风格的字段有两...
基于这些特定模式的频率,我们为每个模块训练一个随机森林分类器。设置 install python3 version 3.6.7install python3-pip # (tested with 9.0.1)pip3 install -r requirements.txt # (tested versions indicated ...
JavaScript 的设计模式 基于和 @ 2015 年 2 月 5 日 蒂亚戈·加西亚 技术经理 技术主管。 组织者。... 具有 23 种经典设计模式,分为创造型、结构型和行为型。 很多人认为“设计模式”一词是这 23
在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而非像C#或其他描述性语言那样仅仅作为一个模块来使用。函数有四种调用模式,分别是:函数调用形式、方法调用形式、构造器形式、以及apply形式...