JavaScript架构设计 1.种子模块

Posted wing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript架构设计 1.种子模块相关的知识,希望对你有一定的参考价值。

1.  种子模块

种子模块也叫核心模块,是框架的最先执行的部分。

粽子模块包含功能:对象扩展,数组化,类型判定,简单的事件绑定与卸载,无冲突处理,模块加载与domReady。本章讲解以mass Framework的种子模块为范本。

1.1  命名空间

种子模块作为一个框架的最开始部分,除了负责辅建全局的基础设施外,你有没有想到给读者一个震撼的开场呢?俗话说,好的开头时成功的一半。

时下“霸主”jQuery 就有一个很好的开头——IIFE(立即调用函数表达式),一下子吸引住读者,让读者吃了一颗定心丸。

IIFE是现代javascript框架最主要的基础设施,它像细胞膜一样包裹自身,防止变量污染。但我们总得在Window里设置一个立足点,这个就是命名空间。

1       if(typeof(Ten) === "undefined") {
2                 Ten = {};
3                 Ten.Function = {}
4                 Ten.Array = {}
5                 Ten.Class = {}
6                 Ten.JSONP = new Ten.Class()
7                 Ten.XHR = new Ten.Class()
8 
9             }

纵观各大类库的实现,一开始基本都是定义一个全局变量作为命名空间,然后对它进行扩展,如Base2的Base、Ext的Ext,jQuery的jQuery、YUI的YUI、dojo的dojo等。从全局变量的污染程度来看,分为两大类。

Prototype、mootools与Base2归为一类。Prototype的哲学是对JavaScript原生对象进行扩展。

第二类是jQuery、YUI、EXT这些框架。YUI与EXT就像上面给出的代码那样,以叠罗汉方式构架的。jQuery则另辟蹊径,它是以选择器为导向的,因此它的命名空间是一个函数,方便用户把CSS表达式字符串传进来,然后通过选择器引擎进行查找,最后返回一个jQuery实例。jQuery初期非常弱小,它想让别人用自己的框架,但也想像Prototype那样使用美元符号作为命名空间。因此它特意实现了多库共存机制,在$,jQuery与用户指定的命名空间中任意切换。

jQuery的多库共存原理很简单,因此后来也成为许多小库的标配。首先把命名空间保存到一个临时变量中,注意这时这个对象并不是自己框架的东西,可能是Prototype.js等巨头的,然后再搞个noConflict放回去。

 1             _jQuery = window.jQuery, _$ = window.$; //先把可能存在的同名变量保存起来
 2 
 3             jQuery.extend({
 4                 noConflict: function(deep) {
 5                     window.$ = _$;//这时再放回去
 6                     if(deep) {
 7                         window.jQuery = _jQuery;
 8                     }
 9                 return jQuery;
10             };

但jQuery的noConflict只对单文件的类库框架有用,想EXT就不能复制了。因此把命名空间改名后,将EXT置为null,然后又通过动态加载方式引入新的JavaScript文件,该文件再以EXT调用,将会导致报错。

mass Framework对JQuery的多库共存进行改进,它与jQuery一样有两个命名空间,一个是美元符号,一个是根据URL动态生成的长命名空间(jQuery就是jquery)

            namespace=DOC.URL.replace(/(#.+|\W)/g,‘‘);

短的命名空随便用户改名,长的命名空间则是加载新的模块时用的,虽然用户在模块中使用$做命名空间,但当JavaScript问及加载下来时,我们会对立面的内容再包一层,将$指向正确的对象,具体实现见define方法。

1.2  对象扩展

我们需要一种机制,将新功能添加到我们的命名空间上。这方法在JavaScript通常被称做extend或mixin。JavaScript对象在属性描述符(Property Descriptor)没有诞生之前,是可以随意添加、更改、删除其成员,因此扩展一个对象非常便捷。一个简单的扩展方法实现是这样。

1             function extend(destination,source){
2                 for(var property in source)
3                     destination[property]=source[property]
4                 return destination;
5             }

不过,旧版本IE在这里有个问题,它认为像Object的原型方法就是不应该被遍历出来,因此for in循环是无法遍历名为valueOf、toString的属性名。这导致,后来人们模拟Object.keys方法实现时也遇到了这个问题。

            Object.keys = Object.keys || function(obj) {
                var a = [];
                for(a[a.length] in obj);
                return a;
            }

不同的框架,这个方法不同的实现,如EXT分为apply与applyIf两个方法,前者会覆盖目标对象的同名属性,而后者不会。dojo允许多个对象合并在一起。jQuery还支持深拷贝。下面是mass Framework的mix方法,支持多对象合并与选择是否覆写。

 1             function mix(target, source) { //如果最后参数是布尔,判定是否覆写同名属性
 2                 var args = [].slice.call(arguments),
 3                     i = 1,
 4                     key, ride = typeof args[args.length - 1] == "boolean" ? args.pop() : true;
 5 
 6                 if(args.length === 1) { //处理$.mix(hash)的情形
 7                     target = !this.window ? this : {};
 8                     i = 0;
 9                 }
10                 while(source = arge[i++]) {
11                     for(key in source) {
12                         if(ride || !(key in target)) {
13                             target[key] = source[key];
14                         }
15                     }
16                 }
17                 return target;
18             }

1.3  数组化

 浏览器下存在许多类数组对象,如function内的arguments,通过document.forms、form.elements、document.links,select.options、document.getElementsByName、childNodes、children等方式获取的节点集合(htmlCollection、NodeList),或依照某些特殊写法的自定义对象。

1             var arrarLike={
2                 0:"a",
3                 1:"1",
4                 2:"2",
5                 length:3
6             }

类数组对象是一个很好的存储结构,不过功能太弱了,为了享受纯数组的那些便捷方法,我们在处理它们前都会做一下转换。

通常来说,只要[].slice.call 就能转换了,但旧版本IE下的HTMLCollection、NodeList不是Object的子类,采用如上方法将导致IE执行异常。我们看一下各大库怎么处理。

 

以上是关于JavaScript架构设计 1.种子模块的主要内容,如果未能解决你的问题,请参考以下文章

《SPA设计与架构》之JavaScript模块化

JavaScript架构设计 2.模块加载系统

《JavaScript设计模式》深入学习 —— Module(模块)模式

密码模块设计

Yarn: 一个新的JavaScript模块管理器

HTML5期末大作业:餐饮美食网站设计——咖啡(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 咖啡网页设计 美食餐饮网页设计...(代码片段