原文地址:http://ghsky.com/2010/09/kissy-research-part-one-kissy.html
看kissy源码不少时间了,有好多地方不明白,今天终于找到一篇文章分析Kissy源码,文章的作者真是厉害啊,分析的真好,看完后真有醍醐灌顶的感觉。感激之心不知怎么表述,贴上语文,顿悟的地方都用红色标注。
==============原文 开始===================
本文着重从KISSY源代码研究,了解KISSY的整体组成,力求从原理上了解KISSY。笔者本人也是边看源代码边进行分析,做了一下笔记,以供大家参考交流,如果有任何不足和错误之处,希望大家提出来学习讨论!
如果你也clone过一份KISSY的源代码,那么从文件组织上面,src文件下的均是源代码文件,依照模块进行划分,这也是KISSY的代码组织的基本方式——模块。在src目录下,又有一个kissy文件夹,里面包含kissy.js,相比肯定是KISSY的核心文件,那今天就先从它下手吧。
首先我们整体看下kissy.js里面都有什么,如下图,对于其中的方法和属性我已经大致做了分类:
首先,KISSY也是要做到对全局对象最小的污染,因此只暴露了一个接口到全局对象中——KISSY,任何KISSY的模块都依附在这个对象上。同时KISSY只提供了弱沙箱的支持,也就是我们直接使用的就是KISSY这个对象,而不是它的一个实例,也就是对于KISSY对象的任何修改都会在全局内产生影响,简单点儿说,例如有KISSY.DOM这样一个DOM相关的模块,但是如果我在自己的代码中不小心将KISSY.DOM = null,这样置空了之后,那么可想而知,后面任何和DOM相关的方法都会报错,这就是弱沙箱的含义。相反,如果我们想像KISSY这是一个类,每次使用前我们需要实例化出一个实例来使用,例如:var ks = new KISSY();,那么ks这个对象相当于和KISSY这个类产生了隔离,我在ks上的任何操作都不会影响KISSY这个全局的类,这就是所谓的强沙箱,YUI3的设计理念正式如此。但 由于KISSY的愿景一样:“小巧灵活,简洁实用,使用起来让人感觉愉悦”,弱沙箱的设置正是权衡之后的提现,在后续的代码分析中,我们会逐渐感受到KISSY这种实用主义的设计理念。
贯穿在kissy.js中的一个最基本的函数就是mix(r, s, ov, wl),其最基本的作用是将一个对象的成员拷贝到另一个对象中,这里的拷贝指的是浅拷贝。这里函数参数的r指的是receiver,也就是拷贝接收对象,s指的是supplier,拷贝的对象提供者。通过ov参数(指的是override)可以将接收者中与提供者重名的属性(方法)覆盖,wl参数(指的是wantlistwhitelist)可以只拷贝列表中指定的属性(方法)。mix函数的逻辑清楚之后,实现起来应该也不是什么问题,这里就不多说了。
源代码中,全部的kissy.js代码都是放到一个(function() {})();匿名函数的闭包中,这就是一个很简单的沙箱,保证了其中的变量不会溢出到全局作用域中,同时我们注意到你们函数的参数列表传入了win, S, undefined几个参数,其中win是window对象,S是'KISSY'字符串,也就是我们暴露到全局对象中的唯一接口的名称,undefined参数实际作用就是指代undefined,这样写的好处是,我们在调用你们函数的时候没有给undefined参数传值,那么其值就是undefined,由于undefined是一个关键字,代码压缩的时候是不能够压缩的,因此这里用参数undefined这个变量(注意,这时候undefined已经是一个变量了而不再是一个值),来代替undefined值,代码压缩的时候自然就可以将这个参数给放心的压缩了,而不用考虑到其是一个关键字而不能压缩,这实际是一个小技巧,保证代码压缩的时候能够尽最大可能被缩短,后面定义的各种变量,很多变量在一定程度也是为了达到提高压缩率的作用,比如刚刚提到的win参数,后面定义的doc = win['document'], loc = location类似的都是为了达到提供代码压缩率。同时对于对象访问,不仅可以提高代码压缩率,同时也可以提高访问效率。我们还注意到一些常量的定义,其基本考虑也是提供代码压缩率,在大量出现常量的地方,使用一个变量存储,之后代码的压缩率可以提高很多。关于JavaScript代码压缩这块的文章,可以Google一下,或者看下这个Slide。
我们整体看下kissy.js里面的代码组织,首先我们有了一个全局的接口对象S(window['KISSY']的一个快捷方式),然后我们有一个mix方法,现在我们便可以很方便地将各种属性、方法mix到S上面,这样组织的好处就是我们不必纠结到底要把这些代码放到哪个对象上,因为只用简单地修改一下mix的参数,便能将代码很容易的转移到其他对象上。那现在我们需要往KISSY这个对象上mix哪些东西呢?首先最基本的,版本信息,类库的配置信息(主要是是否开启debug模式,以及load加载相关参数),还有一个最重要的是类库的模块存储。既然我们这前说过KISSY代码最基本的组织方式是以模块方式结合,比如有DOM模块,Event模块,Node模块等系统提供的模块,还有一些用户自定义添加的模板,那么他们都需要存储,那存储到哪里比较合适呢?很自然的想法就是在KISSY对象上开辟一个对象来存储他们,这里便是Env对象的作用,里面的mods存放了各种添加的模块,而_loadQueue则用于load机制的控制。有关模块的设计理念,组织和加载等,我们在后续讲到KISSY的load机制时再详细介绍。
现在类库相关的东西都存储好了,剩下的就是一大堆方法。其中直接依附到KISSY这个对象上的方法一定,其作用一定要是全局的,当然也是最重要的,他们主要包括这么几类:类库、子类库(应用)代码的组织工具,类库加载、调用工具,语言工具(JavaScript语言增强、修补),类库调试工具,这些工具最终决定了整个类库的代码组织方式,子类库组织方式,OO风格,类库合适加载、执行,类库调试等方式。但是现在我们仅仅考虑kissy.js,实际上我们可以发现,在kissy目录下的所有代码,最终实际都是直接附加到KISSY对象上,他们可以构成整个KISSY类库的最核心部分,实际上有了这个core,我们便可以用其方便地创建各种子类库或者应用,而实际其他模块加入到其中,简单一点说只是为了方面我们创建各种与浏览器相关的东东,因此core就像一个设计精巧的机器人(攻城师),事在人为嘛,其实有人就够了,但是毕竟需求那么多、那么强大,我们只好给这个机器人进行全副武装(往其中添加各种模块),最后我们便能完成“攻城”,利用这些利器攻克一个个顽固的需求。
继续往下分析,我们会注意到一个ready方法,他的本质就是在DOM加载完成后触发的一个回调,按照我们刚刚的理论,实际上DOM相关的方法因为是按模块方式加入到KISSY中,core应该尽量保持简洁,那为什么这里要在core中直接出现一个DOM相关的方法呢?我们可以把脚本加载启动想像为一台电脑启动,我们core的作用就相当于一个引导程序的作用,提供了最基本的工具引导主要脚本加载、使用,而何时能够开始启动其他程序这就是DOM ready的作用,因为其不受业务脚本的影响,只于页面内容本身有关,因而起到了在DOM ready后,引导业务脚本执行的作用,因此把ready方法放在core中是考虑到脚本的实际使用情况。对于ready这个方法,考虑到一定会被多次调用,DOM ready前需要把注册了的所有函数保留起来,DOM ready之后,就需要依次执行所有注册过的函数即可。因此需要设置两个状态变量,一个用于记录DOM ready事件是否已经注册监听,另一个需要记录是否已经DOM ready,同时还需要一个队列保存所有需要执行的函数。对于注册DOM ready事件,兼容性是一个比较棘手的问题,这里推荐几篇文章模拟兼容性的 addDOMLoadEvent 事件,YUI 中 onDOMReady 的 iframe bug,在kissy.js里面分别用_bindReady方法和_fireReady方法作为内部调用,来注册DOM ready事件已经DOM ready后触发函数调用。和ready方法类似,只不过available方法是用于检测元素是否可用,原理也很简单,可以反复调用getElementById函数,检测元素是否找到即可判断是否可用了,只是需要保证一定的测试延迟以及探测次数。
对于类库,同样需要提供构建构建OO代码的最基本方法,最开始说到的mix方法可以视作之一,由于JavaScript语言的特殊性,其OO方式也与其他传统语言的OO不一样,merge,augment,extend三个方法都或多或少的用到了mix,其中merge和augment两个方法可以视作mix的特殊定制、改良版本。merge,顾名思义,将参数列表中的元素合并,并且满足后向前覆盖的原则,返回一个合并后的对象,同时如果参数只有一个对象的话,就相当于做了一个简单的浅拷贝。augment方法是将提供者的prototype对象(或者自身)合并到接收者的prototype上,正如其名字一样的,扩大接收者的prototype对象。extend方法则用来提供较为完善的继承机制,包括继承父类的prototype,修复自己prototype的constructor,添加superclass属性用于向上访问到父类,同时可以提供参数用于覆盖prototype上的方法(属性),或者覆盖类方法(属性)(这里的类方法可以理解为静态方法,即直接写于构造函数上的方法(属性))。
基于类库需要构造相关的应用,就需要考虑到命名空间的问题,kissy.js里面提供了namespace和app两个方法来解决这个问题。首先namespace方法是用于返回一个指定命名空间用于存放东西的,而app方法则会基于KISSY对象,拷贝指定方法,返回一个新的对象,里面包含KISSY的基本配置以及完善的模块、load机制,这里的app主要是用来组织一个应用级别的代码体系,由于包含完整的模块和load机制,每个应用都可以有自己的模块,这就相当于就有较大的可自定义性,而不用考虑KISSY自身的模块。正如现在淘宝的组织方式,首页就是一个app,包含了各个模块,这样就可以基于首页这个独立应用来考虑模块的组织,而不用担心将首页模块添加到KISSY模块中产生的混乱。
最后还有两个简单的有关类库的调试工具,这里就不详细介绍了。
现在已经对kissy.js中附加到KISSY对象上的方法有了大致的了解,最后KISSY对象的初始化配置函数还是需要再提一下,这个方法叫__init,也是直接依附与KISSY对象上,从命名上就可知道是仅供内部使用的,这个方法主要是做什么事儿呢?首先是要初始化KISSY对象的模块容器,同时设置相关的配置属性,这里的base主要是用于模块加载时候使用的,它的值就是当前KISSY执行脚本的地址,之后各个模块就可以通过这个地址进行定位,获取加载路径,这样加载起来就很智能,只需要部署的时候按照目录放置文件,后续的模块加载就没问题。
现在提及了很多模块的有关概念,下次我们会重点了解一下KISSY的模块机制以及加载方式,从中大致了解KISSY的设计理念。
分享到:
相关推荐
这个“Kissy学习教程”压缩包文件包含了深入理解并掌握Kissy的资源,帮助开发者快速上手和应用Kissy到实际项目中。 在学习Kissy之前,我们首先要了解JavaScript库的基本概念。JavaScript库是一组预先编写好的...
1. **模块化**:Kissy 基于CommonJS规范,采用模块化的设计思想,允许开发者将代码分割成多个模块,每个模块专注于特定的功能,便于代码的重用和维护。通过`require`和`exports`关键字,我们可以方便地引入和导出...
为了帮助大家更好地理解和应用KISSY框架,教程作者明河编写了这套KISSY学习教程,旨在通过系统完整的讲解,使初学者能够快速上手并精通KISSY框架。 在KISSY学习教程中,首先介绍了KISSY框架的基本概念,包括它的...
1. **模块化**:Kissy 提倡模块化开发,它基于AMD(Asynchronous Module Definition)规范,允许开发者将代码分解为可重用的模块,便于管理和维护。通过`require`和`define`方法,可以方便地组织和加载模块。 2. **...
1. **模块化管理**:Kissy 强调模块化开发,采用 CommonJS 规范,允许开发者将代码分解为独立的模块,便于组织、重用和维护。每个模块都可以独立加载,降低了页面的加载时间,提高了性能。 2. **兼容性广泛**:...
1. **模块化**:Kissy基于CommonJS规范实现模块化,允许开发者将代码分割成多个模块,每个模块独立加载,减少页面初始化时的负担。这种模块化设计使得代码组织更有序,易于维护和扩展。 2. **兼容性**:Kissy对各种...
标题中的“Kissy Suggest”是指Kissy框架中的一个组件,Kissy...对于想要学习或使用Kissy Suggest的开发者来说,这些信息是非常宝贵的,他们可以从这些资源中学习如何在自己的项目中有效地利用这个组件,提升用户体验。
1. **源代码**:Kissy 框架的核心模块和扩展组件,这些代码通常位于 "src" 目录下,分为基础组件和可选模块,如事件系统、DOM 操作、动画效果等。 2. **构建脚本**:用于编译、压缩和合并代码的工具,如 Grunt 或 ...
1. **模块化设计**:Kissy Editor遵循Kissy框架的模块化思想,将各种功能如图片上传、表格操作、链接插入等拆分成独立模块,开发者可以根据需要选择加载,这样既节省资源,又方便定制。 2. **插件体系**:Kissy ...
1. **界面美观**:Kissy Editor提供了直观且友好的用户界面,设计风格简洁,色彩搭配和谐,使得用户在编辑过程中拥有良好的视觉体验。此外,编辑器支持自定义皮肤,可以根据项目需求进行个性化定制。 2. **插件扩展...
1. 小巧灵活:Kissy Web编辑器的体积小,加载速度快,不会对网站性能造成过大负担。它通过优化代码和减少不必要的组件,实现了在网页环境中快速响应用户操作,提供了流畅的编辑体验。同时,其灵活性体现在可以轻松地...
在本文中,我们将深入探讨如何使用JavaScript库KISSY来实现一个类似阿里云滑动下拉导航菜单的效果...在压缩包提供的代码中,你将找到这些概念的具体实现,通过阅读和学习,你可以深入了解KISSY框架在实际项目中的应用。
在前端开发领域,JavaScript是一种不可或缺的编程语言,它赋予了网页动态交互的能力。...对于想要学习和提升前端开发技能的人员,这是一个很好的实践项目,可以帮助他们深入理解和掌握KISSY框架的应用。
同时,由于KISSY的API设计清晰,学习曲线相对平缓,对于新接触的开发者来说,上手速度较快。 总的来说,KISSY以其高效、灵活的设计,为前端开发提供了强大的支持。通过合理利用其模块化、事件系统和Ajax等功能,...
【标题】"基于KISSY的四角遮罩特效.zip" 涉及的主要知识点是JavaScript前端开发中的...学习和理解这个案例,可以帮助开发者更好地掌握JavaScript编程技巧和KISSY框架的使用,从而在实际项目中创建更多创新的前端特效。
1. **KISSY框架**:KISSY是阿里巴巴开源的一个JavaScript库,它的设计理念是简洁、易用、高效。KISSY采用模块化开发方式,允许开发者按需加载所需模块,降低了代码体积,提高了页面加载速度。通过KISSY,开发者可以...
kissy-mobile KISSY Mobile 是阿里巴巴内部项目Kissy MINI fork出来的项目。是面向移动终端的KISSYApp....我希望可以把这个框架放在github供大家学习交流并改进之。希望它可以为中国的程序员开发移动端H5提供一个选项。
JavaScript Kissy 是一个轻量级、模块化的前端开发框架,由淘宝团队开发并维护,旨在提升前端开发效率,实现代码的可复用...通过学习和掌握Kissy,开发者可以提升开发效率,降低维护成本,为用户提供更优质的用户体验。
在前端开发中,图片裁剪功能常常被用于用户头像上传、产品图片编辑等场景,以提供更加个性化和...通过学习和研究这个案例,开发者可以加深对前端图像处理、事件处理以及库的使用等方面的理解,提高自己的前端开发能力。
1. **KISSY框架**:KISSY的核心理念是"Keep It Simple and Stupid",它提供了一种简单易用的方式来组织和管理JavaScript代码,支持AMD(Asynchronous Module Definition)模块加载机制,使得代码可以按需加载,提高...