第二章 : 种子模块

种子模块也叫核心模块,是框架中最先执行的部分。即便像jQuery那样的单文件函数库,它的内部也分很多模块,必然有一些模块执行时在最前面立即执行,有一些模块只有用到才执行。有的模块可有可无,存在感比较弱,只有在特定的浏览器下才运行。

种子模块就是其中的先锋,它里边的方法不一定要求个个功能齐全,设计优良,但一定要极具扩展性,常用,稳定。

扩展性是指通过他们能给将其它模块包含进来;常用是指绝大多数的模块都能用到它们,防止做重复工作。稳定是指在版本迭代时不轻易被新方法替代。

参照许多框架和库的实现,我们认为种子模块包含如下功能对象扩展数组化类型判定简单的绑定与卸载无冲突处理模块的加载domReady.本章学习的内容以mass Framework种子模块为范本。

https://github.com/RubyLouvre/mass-Framework

命名空间

种子模块作为一个框架最开始的部分,负责辅建全局的基础设施外。jQuery就有一个很好的开头,使用LIFE(立即调用函数表达式).

LIFE是现代javascript框架里最主要的基础设施,它就像细胞一样包裹自身,防止变量污染。就像一个立足点,这个就是命名空间,如prototype.js,mootools,它们让你感受不到框架的存在,它的意义深刻到javascript、DOM、BOM等整个执行环境的每个角落,对原生的对象原型就行扩展。由于道格拉斯(JSON作者)的极力反对,新的框架都在命名空间上构建了。

我们看怎么在javascript上模拟命名空间。javascript一切基于对象,但只有符合类型的对象才符合要求,比如function 、RegExp、Object,不过最常用的是object和function。我们往一个对象上添加一个属性,而这个属性又是一个对象,这个对象我们又可以为它添加一个对象,通过这种方法,我们就可以有条不紊的构建我们的框架。用户想调用某个方法,就以xxx.yyy.zzz()的形式调用。

    if( typeof(Ten) === "undefined" ){
        Ten = {};
        Ten.Function = {  /*略*/ }
        Ten.Array = {  /*略*/ }
        Ten.Class = {  /*略*/ }
        Ten.JSONP = new Ten.Class(/*略*/ )
        Ten.XHR = new Ten.Class(/*略*/ )
    }

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

prototype.js和mootools与Base2归为一类,Prototype的哲学是对javascript的原生对象进行扩展。早些年,prototype差点称为事实的标准。因此没有考虑到与其它库共存的问题。基本Prototype,也发展出诸如script.aculo.us,rico,Plotr,protoChart,Script2等非常优秀的类库以一大类收费插件。而且,有些渊源的插件几乎都与Prototype有关,比如lightBox。mootools是prototype.js的升级版,更加OO,全面复制其API。Base2则是想修复IE的bug,让IE拥有标准浏览器的API,因此也把所有原生的对象污染一遍。

第二类是jQuery,YUI,EXT这些框架YUI和Ext就是对象嵌套对象的方式构建的。jQuery则另辟蹊径,它是以选择器为导向的,因此它的命名空间是一个函数,方便用户将css表达器的字符串传进来。然后通过选择器进行查找,最后返回一个jQuery对象实例。

jQuery最开始也像Prototype使用$作为它的命名空间,因此,它实现了很多库的共存机制,在$和jQuery中任意切换,jQuery的多库共存原理很简单,因此后来也成为许多小库的标配。首先,把命名空间保存到一个临时变量中(注意,这时候这个对象并不是自己框架的东西,可能是prototype.js或者其他的),然后再使用个noConflict放回去。

    //jQuery1.2
    var _jQuery = window.jQury , _$ = window.$; //把可能存在同名变量先保存起来
    jQury.extend({
        noConflict : function(deep) {
            window.$ = _$; //这时再放回去
            if (deep)  //补充 if ( deep && window.jQuery === jQuery )
                window.jQury = _jQuery;
            return jQury;
        }
    })

参考:http://zhidao.baidu.com/question/1239712776390687219.html

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

对象扩展

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

    function extend (destination,source){
        for (var property in source)
            destination[property] = source[property];
        return destination;
    }

不过,旧版本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 Farmework的mix方法。支持多对象合并与选择是否覆写。

    function mix(target,source){ //如果最后参数是布尔,判定是否覆盖同名属性
        var args = [].slice.call(arguments), i = 1, key,
            ride = typeof args[args.length - 1] == "boolean" ? args.pop() : true;
        if (args.length === 1){ //处理$.mix(hash)的情形
            target = !this.window ? this : {};
            i = 0;
        }
        while ((source = args[i++])) {
            for (key in source){ //允许对象糅杂,用户保证都是对象
                if (ride || !(key in target)) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    }

未完待续

数组化

类型的判定

主流框架的引入机制-domReady

无冲突处理

上一章:第一章 : javaScript框架分类及主要功能

时间: 2024-09-29 22:07:47

第二章 : 种子模块的相关文章

Head First Python 第二章 函数模块&第三章 文件与异常&第四章 持久存储&第五章 处理数据

第三章 1.共享模块 模块和发布工具箱全世界共享模块 编写函数,以.py为文件后缀名,第三方库都在PyPI *注释代码:三引号(单双都可以) 发布过程P40 使用发布工具,函数模块变成了一个“发布”,可以使用import导入其他程序 2.如果函数模块功能不满意 添加参数以供api选择比添加函数工作量小! 首先考虑BIF内置函数 ----------------------------------------------------------- 第四章 1.文件 open()语句,readlin

第三章:模块加载系统(requirejs)

任何一门语言在大规模应用阶段,必然要经历拆分模块的过程.便于维护与团队协作,与java走的最近的dojo率先引入加载器,早期的加载器都是同步的,使用document.write与同步Ajax请求实现.后来dojo开始以JSONP的方法设计它的每个模块结构.以script节点为主体加载它的模块.这个就是目前主流的加载器方式. 不得不提的是,dojo的加载器与AMD规范的发明者都是james Burke,dojo加载器独立出来就是著名的require.本章将深入的理解加载器的原理. 1.AMD规范

关于《大道至简》第二章的收获

今天阅读了大道至简的第二章,这一章的标题是懒人造就了方法.文章以愚公和李冰作为例子,讲述了好的方法是如何产生的.由此我们可以想到身边的一些例子,假如我们要给一些学生出算数题,题量不大的情况下我们可以直接出题,当要求题量的时候这就是一个大工程了.为此,我们可以写一个简单的软件实现出题的功能.虽然写这个软件会花费一些时间,但是完成之后会省下很大的精力. 我们应该学会将源代码分写在几个文件中,而不是所有的都写在一起,因为都放在一个文件中,到了后期的维护可能会是很大的问题,因此Unit关键字出现了,将一

《linux内核设计与实现》第二章

第二章 从内核出发 一.获取内核源码 1.使用Git(linux创造的系统) 使用git来获取最新提交到linux版本树的一个副本: $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git 下载代码后,更新分支到Linux的最新分支: $ git pull 这两个命令可以获取并随时保持与内核官方的代码树一致. 2.安装内核源代码 压缩形式是bzip2,则运行: $ tar xvjf linu

大道至简第二章—懒人的方法

大道至简第二章—懒人的方法 僰道有故蜀王兵阑亦有神,作大滩江中.其崖崭峻,不可凿:乃积薪烧之.故其处悬崖有赤白五色. ----华阳国志卷三-蜀志 在第一章中作者引用愚公移山的典故向我们介绍了编程的精义,以愚公为例向我们介绍了个编程人员应具备的素质.而在第二章,作者通过蜀郡太守李冰烧石破山建造都江堰的故事告诉我们我们只是勤奋是不够的.如果李冰像愚公那样日复一日的敲石碎山,就不会有空闲时间去观察,去思考了.那也不会有“积薪烧之”的事情了.所以李冰乃是闲人一枚. 人的精力是有限的.愚公而愚公可以多吃点

大道至简:软件工程实践者的思想第二章读后感

第二章:是懒人造就了方法 引用典故李冰烧山的故事,同是战国时期,愚公就要“碎石击壤”,而李冰就已经懂得“积薪烧之”了,为什么说懒人造就了方法呢,假如李冰也像愚公一样没日没夜的督促他的团队凿石开山,那么他肯定没有时间来学习.寻找或者观察,当然也不会发现“烧”这种方法可以加快工程进度,使得一大座山短时间就被哗啦哗啦地给“碎”掉了. 李冰的团队成百上千,若只为吃喝拉撒,那必然会寝食难安,因为工程太过巨大.相反,他应是个闲人,可以闲到去观察火能否把石头烧爆.在如此大的工程中,如果会闲到去看石头,那他一定

第二章 【面向对象设计原则】

(一)如何衡量软件设计的质量 内聚度: 表示一个应用程序的单个单元所负责的任务数量和多样性.内聚与单个类或者单个方法单元相关.(好的软件设计应该做到高内聚.) 耦合度: 耦合度表示类之间关系的紧密程度.低耦合是指尽量使用抽象耦合,少用具体耦合. 设计原则名称 设计原则简介 重要性 单一职责原则 的职责要单一,不能将太多的职责放在一个类中. ★★★★☆ 开闭原则 软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能.  ★★★★★ 历史替换原则 在软件系统中,一个可

白帽子讲Web安全 第二章 浏览器安全

第二章  浏览器安全 1.同源策略 它是由Netscape提出的一个著名的安全策略. 现在所有支持JavaScript的浏览器都支持这个策略. 同源是指:协议.端口.域名相同. eg:当一个浏览器的两个tab页中分别打开谷歌和百度页面时, 当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的, 即检查是否同源,只有和百度同源的脚本才会被执行. 浏览器的同源策略,限制了来自不同源的"document"或脚本,对当前"document"读取或设置某些属

Android开发艺术探索——第二章:IPC机制(上)

Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化机制和Binder,然后详细的介绍Bundle,文件共享,AIDL,Messenger,ContentProvider和Socker等进程间通讯的方法,为了更好的使用AIDL进行进程间通讯,本章引入了Binder连接池的概念,最后,本章讲解各种进程间通信方式的优缺点和使用场景,通过本章,可以让读者对