- 浏览: 663039 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
lizaochengwen:
网络请求碰到的中文乱码使用encodeURL吧- (NSStr ...
iPhone开发/iPad开发 中文乱码问题 -
hhb19900618:
还是没弄懂怎么解决了中文乱码? 正确代码能重写贴出吗
iPhone开发/iPad开发 中文乱码问题 -
zhengjj_2009:
我的理解是讲ipa文件解压缩之后再重新打包,已经破坏了签名,所 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
zhengjj_2009:
我参考你的“ 从ipa格式的母包生成其它渠道包的shell脚本 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
同一片天空:
问题果然解决了
iOS 搭建 XMPP实现环境
前言
模块模式是基于js闭包实现的一个模式,这篇文章描述如何用模块模式来支持多人大型项目,此外,需要自己做框架的同学也可以参考。
-煎蛋
模块模式深度探索模块模式是一个常用的js编程模式。它很好理解,但是还有一些高级的使用方法没有引起广泛的注意。这篇文章,我将回顾一些不寻常的高端话题,其中一个是我自认为原创的。
基础
我们先来简述一下模块模式。三年前YUI的Eric Miraglia首先发博客(http://yuiblog.com/blog/2007/06/12/module-pattern/)提到这个模式后,模块模式变得广为人知。如果你已经非常了解模块模式,可以跳到"高级模式“的段落。
匿名闭包
匿名闭包是让一切成为可能的基础,而且这也是javascript最好的特性。我们创建个简单的匿名函数(anonymous function)看看。函数内运行的代码都存在于闭包内,这个闭包在整个应用的生命周期内都保持私密和自己的状态(privacy and state)。
(function () {
// 所有的var和function都只存在于当前作用域内
// 仍然可以读取到所有的全局变量
}());
注意 包住匿名函数的"()"。这是JS语言本身的要求,因为由function开头的代码一律被识别为"函数声明",用()包住则创建了一个函数表达式。
*** http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2009/12/named-function-expressions-demystified.html 关于函数声明VS函数表达式 ***
Global Import 引用全局变量
js有个特质”隐含的全局变量“(implied globals)。无论一个name是否使用过,JS解释器反向遍历作用域链查找这个name的var声明,如果没找到var,则这个对象是全局的。这意味着在一个匿名闭包中使用和创建全局变量很容易。不幸的是这让代码难与管理,对阅读代码的人来说很难区分哪些变量是全局的。
幸好,我们的匿名函数提供了一个简单的替代方案。将全局变量作为参数传入匿名函数,这比用隐含全局变量更清晰更快速。例子:
Module Export 模块导出
当你不仅仅想使用全局变量,还想声明一些(全局变量)的时候。我们可以很方便地用匿名函数的返回值来导出(全局变量)。 这么做就是一个完整的模块模式基本形态。例子:
我们声明了一个全局变量”MODULE”, 有两个公有属性: 分别是一个方法MODULE.moduleMethod和一个变量MODULE.moduleProperty。除此之外,它用匿名函数的闭包保持自己的私有内部状态。同时根据上一个例子,我们还可以很方便的引用全局变量。
高级模式
上面的内容对大多数用户已经很足够了,但我们还可以基于此模式发展出更强大,易于扩展的结构。
Augmentation增生
模块模式的一个限制是整个模块必须写在一个文件里。在大型编码项目里工作的人都知道代码分成多个文件的重要性。(再次)幸好,我们又一个很好的解决方案 augment modules
首先,我们导入模块,然后我们添加属性,然后我们再把它导出。例子:
为确保一致性我们再次使用var关键字,尽管这不是必须的。代码运行后,我们的模块会获得一个新的公有方法MODULE.anotherMethod。这个增生的文件也保持自己的私密性,内部状态和对他的导入。
Loose Augmentation松散增生
我们的上一个例子要求我们的初始化模块必须先运行。而增生必须第二步发生。这不应该是必要的。
js的好处之一就是可以异步的读取脚本文件。我们可以创建灵活的多块的模块,用Loose Augmentation,他们可以按任何顺序加载自己。每个文件应该有如下的结构:
在这个模式下,var声明总是必须的注意如果模块还不存在,导入就会新建模块。这意味着你可以使用类似LABjs(http://labjs.com/)这样的工具并行的读取所有你的模块文件,没有任何的阻塞(block)
Tight Augmentation紧密增生
虽然松散增生很牛叉,但是这对你的模块有一定的限制。最重要的是你不能安全的重载(override)你的模块属性.你也不能在初始化的时候就使用模块的属性。紧密增生包含一个加载顺序,但是允许重载(override).例子:
这样我们重载(override)了MODULE.moduleMethod,但如果需要,仍可保持对原方法的引用。
Cloning and Inheritance 克隆和继承
Cross-File Private State跨文件私有状态
将一个模块划分到多个文件的限制之一是每个文件保持它自己的私有状态,而且不能解接入其他文件的私有状态。这是可以解决的,下面的例子用松散增生模块在多个增生之间保持私有状态:
任何文件都可以对他们的局部变量_private设属性,并且设置对其他的文件也立即生效。一旦这个模块加载结束,应用会调用MODULE._seal()"上锁",这会阻止外部接入内部的_private。如果这个模块需要再次增生,应用的生命周期内,任何文件都可以调用_unseal() ”开锁”,然后再加载新文件。加载后再次调用 _seal()”上锁”
Sub-modules子模块
我们最后的高级模式是最简单的,有很多好例子来创建子模块,就像创建一个普通的模块
MODULE.sub = (function () {
var my = {};
// ...
return my;
}());
尽管这很明显,但我认为还是值得加进来的,子模块具有一般模块所有的高级能力,包括增生和私有状态。
/*==豆瓣javascript组译文2==*/
总结
大多数高级模式可以与其他的互相组合形成有用的模式。如果让我来设计一个复杂应用的架构,我会组合使用loose augmentation, private state, 和 sub-modules.
最后,这里有个sub-module动态的把自己加载到父模块去(如果没有则创建)。为了简洁,我没有包含private state。这段代码允许一个复杂的大型分层代码库并行的加载自己和他的子模块:
未校对,有两句还有翻译,请路过的同学提供这方面的协助
-END-
原文: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
模块模式是基于js闭包实现的一个模式,这篇文章描述如何用模块模式来支持多人大型项目,此外,需要自己做框架的同学也可以参考。
-煎蛋
模块模式深度探索模块模式是一个常用的js编程模式。它很好理解,但是还有一些高级的使用方法没有引起广泛的注意。这篇文章,我将回顾一些不寻常的高端话题,其中一个是我自认为原创的。
基础
我们先来简述一下模块模式。三年前YUI的Eric Miraglia首先发博客(http://yuiblog.com/blog/2007/06/12/module-pattern/)提到这个模式后,模块模式变得广为人知。如果你已经非常了解模块模式,可以跳到"高级模式“的段落。
匿名闭包
匿名闭包是让一切成为可能的基础,而且这也是javascript最好的特性。我们创建个简单的匿名函数(anonymous function)看看。函数内运行的代码都存在于闭包内,这个闭包在整个应用的生命周期内都保持私密和自己的状态(privacy and state)。
(function () {
// 所有的var和function都只存在于当前作用域内
// 仍然可以读取到所有的全局变量
}());
注意 包住匿名函数的"()"。这是JS语言本身的要求,因为由function开头的代码一律被识别为"函数声明",用()包住则创建了一个函数表达式。
*** http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2009/12/named-function-expressions-demystified.html 关于函数声明VS函数表达式 ***
Global Import 引用全局变量
js有个特质”隐含的全局变量“(implied globals)。无论一个name是否使用过,JS解释器反向遍历作用域链查找这个name的var声明,如果没找到var,则这个对象是全局的。这意味着在一个匿名闭包中使用和创建全局变量很容易。不幸的是这让代码难与管理,对阅读代码的人来说很难区分哪些变量是全局的。
幸好,我们的匿名函数提供了一个简单的替代方案。将全局变量作为参数传入匿名函数,这比用隐含全局变量更清晰更快速。例子:
(function ($, YAHOO) { // 使用全局的 jquery 比如$ 和 YAHOO }(jQuery, YAHOO));
Module Export 模块导出
当你不仅仅想使用全局变量,还想声明一些(全局变量)的时候。我们可以很方便地用匿名函数的返回值来导出(全局变量)。 这么做就是一个完整的模块模式基本形态。例子:
var MODULE = (function () { var my = {}, privateVariable = 1; function privateMethod() { // ... } my.moduleProperty = 1; my.moduleMethod = function () { // ... }; return my; }());
我们声明了一个全局变量”MODULE”, 有两个公有属性: 分别是一个方法MODULE.moduleMethod和一个变量MODULE.moduleProperty。除此之外,它用匿名函数的闭包保持自己的私有内部状态。同时根据上一个例子,我们还可以很方便的引用全局变量。
高级模式
上面的内容对大多数用户已经很足够了,但我们还可以基于此模式发展出更强大,易于扩展的结构。
Augmentation增生
模块模式的一个限制是整个模块必须写在一个文件里。在大型编码项目里工作的人都知道代码分成多个文件的重要性。(再次)幸好,我们又一个很好的解决方案 augment modules
首先,我们导入模块,然后我们添加属性,然后我们再把它导出。例子:
var MODULE = (function (my) { my.anotherMethod = function () { //添加一些方法 }; return my; }(MODULE));
为确保一致性我们再次使用var关键字,尽管这不是必须的。代码运行后,我们的模块会获得一个新的公有方法MODULE.anotherMethod。这个增生的文件也保持自己的私密性,内部状态和对他的导入。
Loose Augmentation松散增生
我们的上一个例子要求我们的初始化模块必须先运行。而增生必须第二步发生。这不应该是必要的。
js的好处之一就是可以异步的读取脚本文件。我们可以创建灵活的多块的模块,用Loose Augmentation,他们可以按任何顺序加载自己。每个文件应该有如下的结构:
var MODULE = (function (my) { // 添加一些功能 return my; }(MODULE || {}));
在这个模式下,var声明总是必须的注意如果模块还不存在,导入就会新建模块。这意味着你可以使用类似LABjs(http://labjs.com/)这样的工具并行的读取所有你的模块文件,没有任何的阻塞(block)
Tight Augmentation紧密增生
虽然松散增生很牛叉,但是这对你的模块有一定的限制。最重要的是你不能安全的重载(override)你的模块属性.你也不能在初始化的时候就使用模块的属性。紧密增生包含一个加载顺序,但是允许重载(override).例子:
var MODULE = (function (my) { var old_moduleMethod = my.moduleMethod; my.moduleMethod = function () { // 重载方法,可通过old_moduleMethod调用旧的方法 }; return my; }(MODULE));
这样我们重载(override)了MODULE.moduleMethod,但如果需要,仍可保持对原方法的引用。
Cloning and Inheritance 克隆和继承
var MODULE_TWO = (function (old) { var my = {}, key; for (key in old) { if (old.hasOwnProperty(key)) { my[key] = old[key]; } } var super_moduleMethod = old.moduleMethod; my.moduleMethod = function () { //在克隆里重载方法,通过super_moduleMethod接入父级(super) }; return my; }(MODULE));
引用
这个模式可能是最灵活的选择。他允许一些neat compositions。这会带来一些灵活性上的代价。I have written it, properties which are objects or functions will not be duplicated, they will exist as one object with two references. Changing one will change the other. This could be fixed for objects with a recursive cloning process, but probably cannot be fixed for functions, except perhaps with eval. Nevertheless, I've included it for completeness.
Cross-File Private State跨文件私有状态
将一个模块划分到多个文件的限制之一是每个文件保持它自己的私有状态,而且不能解接入其他文件的私有状态。这是可以解决的,下面的例子用松散增生模块在多个增生之间保持私有状态:
var MODULE = (function (my) { var _private = my._private = my._private || {}, _seal = my._seal = my._seal || function () { delete my._private; delete my._seal; delete my._unseal; }, _unseal = my._unseal = my._unseal || function () { my._private = _private; my._seal = _seal; my._unseal = _unseal; }; // 持久的接入 _private, _seal, 和 _unseal return my; }(MODULE || {}));
任何文件都可以对他们的局部变量_private设属性,并且设置对其他的文件也立即生效。一旦这个模块加载结束,应用会调用MODULE._seal()"上锁",这会阻止外部接入内部的_private。如果这个模块需要再次增生,应用的生命周期内,任何文件都可以调用_unseal() ”开锁”,然后再加载新文件。加载后再次调用 _seal()”上锁”
Sub-modules子模块
我们最后的高级模式是最简单的,有很多好例子来创建子模块,就像创建一个普通的模块
MODULE.sub = (function () {
var my = {};
// ...
return my;
}());
尽管这很明显,但我认为还是值得加进来的,子模块具有一般模块所有的高级能力,包括增生和私有状态。
/*==豆瓣javascript组译文2==*/
总结
大多数高级模式可以与其他的互相组合形成有用的模式。如果让我来设计一个复杂应用的架构,我会组合使用loose augmentation, private state, 和 sub-modules.
引用
这里我并没有研究性能问题。但是我想顺便提一句:模块模式效率很好。代码量可以更少,使加载代码更快。使用 loose augmentation允许简单的非阻碍式并行加载,这更可以提升下载的速度。初始化时间可能比其他方法要慢,但是这是值得的。Run-time performance should suffer no penalties so long as globals are imported correctly, and will probably gain speed in sub-modules by shortening the reference chain with local variables.
最后,这里有个sub-module动态的把自己加载到父模块去(如果没有则创建)。为了简洁,我没有包含private state。这段代码允许一个复杂的大型分层代码库并行的加载自己和他的子模块:
var UTIL = (function (parent, $) { var my = parent.ajax = parent.ajax || {}; my.get = function (url, params, callback) { // ok, so I'm cheating a bit :) return $.getJSON(url, params, callback); }; // etc... return parent; }(UTIL || {}, jQuery));
未校对,有两句还有翻译,请路过的同学提供这方面的协助
-END-
原文: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
发表评论
-
JavaScript处理事件的一些兼容写法
2012-08-31 14:01 1271绑定事件 var addEvent = funct ... -
javascript深入理解js闭包
2012-03-02 11:21 1072一、变量的作用域 要理解闭包,首先必须理解Javascri ... -
[收藏]javascript keycode大全
2012-02-27 14:14 702keycode 8 = BackSpace BackSp ... -
jquery实现浮动面板 监听页面滚动和大小变化事件
2012-01-31 09:08 4357(function showQQPanel(){ ... -
js与jquery获得页面大小、滚动条位置、元素位置
2012-01-31 09:07 1599//页面位置及窗口大小 function GetPageSi ... -
使用jQuery Mobile开发Web App-页面切换动画 android
2012-01-14 00:48 3129jQuery Mobile包含一组基于CSS3的过渡动画(又称 ... -
HTML5 Canvas 如何取消反锯齿绘图
2012-01-09 23:28 1520HTML5 Canvas 如何取消反锯齿绘图(HTML5 Ca ... -
15 个 HTML5 Canvas 应用欣赏
2012-01-06 13:39 1757HTML5呈现了很多的新特性,这在之前的HTML中是不可见到的 ... -
js浮点数据类型的计算
2012-01-05 23:27 1732JS浮点数据类型的计算,如下实例: //说明:jav ... -
jquery同一元素支持单双击事件
2012-01-05 00:40 2502发表于 2011 年 01 月 20 ... -
meta viewport标签的使用说明(手机浏览缩放控制)
2011-12-31 14:09 1197引用点评:网页手机wap2.0网页的head里加入下面这条元标 ... -
JS 判断浏览器客户端类型(ipad,iphone,android)
2011-12-29 10:15 3987<script type="text/ ... -
jquery ajax方法如load,get等 在CHROME下失效的问题(已经解决
2011-12-28 23:08 1344最近碰到一个问题。jquery在chrome 5.0+ 的版本 ... -
jquery读取xml比较js读取xml 比比就知道
2011-12-28 22:30 4384test.xml: <?xml version=&qu ... -
querySelector 和 querySelectorAll 方法浏览器实现无误,避免将其与 JQuery 的选择器混淆
2011-12-27 23:20 945规范定义 querySelector 和 querySele ... -
js 监听事件,ie 火狐 javascript addEventListener attachEvent
2011-12-27 23:17 1863<head> <script type=' ... -
js中prototype用法
2011-12-27 12:00 540prototype 是在 IE 4 及其以后版本引入的一个针对 ... -
js读取xml
2011-12-26 17:43 696这次准备使用JS来读取XML做一个例子来熟悉下,一共使用了一下 ... -
DOMContentLoaded事件
2011-12-26 17:30 929今天查看百度空间源代码,发现多了个util.js文件,打开看看 ... -
JS- 操作 XML(兼容IE/FF/Chrome,Safari)
2011-12-26 17:26 5489今天同事有需要JS显示XML! 后来就做了一个效果!或许以后能 ...
相关推荐
10. JavaScript的高级技术:可能包括高级函数特性,如递归、闭包、模块模式、命名空间等。 11. 调试和性能优化:提供了一些调试技巧和性能优化的方法,帮助开发者提高代码质量和运行效率。 12. 最新***ript标准:...
但这仅仅是开始,JavaScript的深度和广度远不止于此,随着经验的积累,你将更深入地探索这个语言的魅力,包括前端框架(如React、Vue、Angular)、Node.js后端开发、Web组件化、TypeScript等更多高级主题。
JavaScript、CSS和HTML是构建网页和Web应用的三大核心技术。它们各司其职,共同创造出...在不断学习和实践中,你还可以进一步探索Web开发的深度和广度,如前后端分离、移动Web开发、PWA(渐进式Web应用)等前沿领域。
** RequireJS 入门(一) ** RequireJS 是一个 JavaScript 模块加载器和打包工具,它使得在浏览器环境中可以实现模块化开发,解决了传统 ...希望本文对 RequireJS 的介绍能帮助你快速入门,进一步探索其深度用法。
"高级JavaScript"不仅仅是对基础语法的掌握,更多的是关于语言的深度理解和实践技巧。 1. **原型与原型链** JavaScript中的对象具有原型特性,每个对象都有一个内部`__proto__`属性,这构成了原型链。通过原型链,...
OPJS,全称可能表示“优化的JavaScript”,是关于JavaScript编程的一个个人项目,旨在总结和整理JavaScript以及与之相关的最佳实践、技巧和模式。这个项目可能是一个开发者为了深入理解和掌握JavaScript而创建的学习...
《ArcGIS API for JavaScript:V4.19与V3.36的深度解析》 ArcGIS API for JavaScript是Esri公司开发的一款强大的Web GIS开发工具,它为开发者提供了在Web环境中构建地理信息系统应用的能力。本篇将深入探讨V4.19和V...
**JavaScript 高级程序设计** 是一门深度探讨JavaScript编程技巧和高级特性的课程,适合已经掌握基础语法并希望提升技术水平的开发者。JavaScript,作为一种广泛应用于Web开发的脚本语言,其高级特性对于创建高效、...
### CALIS资源整合与服务模式——云计算等新技术下的探索 #### IT技术发展背景 随着信息技术的不断进步和发展,从主机时代到现在的云计算时代,信息技术经历了多次革新。从最初的集中式主机系统,到分布式客户端/...
《使用JavaScript构建在线计算器的深度探索》 在当今数字化时代,计算工具无处不在,而在线计算器作为其中一员,以其便捷性和灵活性受到广大用户的喜爱。本文将详细探讨如何使用JavaScript这一强大的脚本语言,构建...
同时,JavaScript的异步特性也会在某些模式(如观察者模式)中得到体现,增加了学习的深度和广度。 总的来说,"hwrk-patterns"项目为学习和实践JavaScript设计模式提供了一个实用的平台,是提升BSA-20课程中软件...
闭包常用于创建私有变量和封装行为,如模块模式和函数工厂。 4. **柯里化(Currying)**:柯里化是一种将接受多个参数的函数转换为一系列接受单一参数的函数的技术。这有助于解耦函数的参数,使函数更具可复用性。...
《mmm:构建模块化超框架的深度探索》 在当今的Web开发领域,JavaScript作为前端领域的主导语言,其生态系统不断发展,框架与库层出不穷。其中,“mmm”(成熟-模块化-超框架)作为一种模块化的元框架,为开发者...
《FoundryStats:深入探索在Foundry VTT中的Combatstat模块》 在虚拟桌面角色扮演游戏(Virtual Tabletop,简称VTT)的世界里,Foundry Virtual Tabletop(Foundry VTT)是一个广受欢迎的平台,它允许玩家和游戏...
17. **React Hooks深度探索**:深入研究新出现的Hooks,如`useEffect`, `useRef`, `useCallback`, `useContext`等,以及它们如何简化React开发。 18. **React与外部库集成**:了解如何将React与其他库(如Redux、...
### 面向Java开发人员探索Google Web Toolkit:深度解析与应用 Google Web Toolkit(GWT)是一款由Google推出的开源框架,专为Java开发者设计,旨在简化和加速Web应用程序的开发过程。它允许开发者使用Java语言编写...
【付羽官方个人网站——JavaScript技术深度探索】 付羽2014.github.io是一个由前端开发者付羽创建的个人网站,主要展示了他在JavaScript领域的技术积累和项目经验。这个网站不仅是一个个人品牌展示的平台,也是一个...
《ueditor源码解析与深度探索》 ueditor是一款由百度公司开发的开源富文本编辑器,它以其功能强大、易用性好、兼容性强等特点,广泛应用于网站内容编辑、后台管理系统等领域。ueditor源码的深入理解对于开发者来说...
本项目“基于JAVA的在线购物系统”正是对这一领域的深度探索与实践,旨在提供一个全面的、可操作的网上购物平台开发指南,帮助开发者了解并掌握B2C系统的核心技术。 一、JAVA在B2C系统中的应用 JAVA作为一种跨平台...
《JavaScript V2.0参考大全第二版》是一本深度探讨JavaScript编程语言的权威指南,尤其针对JavaScript的2.0版本进行了详细的阐述。该书的CHM格式版本包含了丰富的技术信息和实用示例,旨在帮助开发者深入理解并熟练...