基于Javascript原型的Zepto框架设计
2018-05-15王运倪静
王运 倪静
摘 要:随着互联网的普及,前端技术也得到了迅速发展。为了深入了解前端开发中的框架设计原理,以Zepto前端框架为例,利用Javascript原型链的相关知识,采用原生Javascript与框架对比的方法剖析了框架整体设计思路,细致分析了框架的大致架构,重构了Zepto对象原型,并封装了可能用到的所有方法。利用这种从宏观到微观的研究视角,最终呈现了一个框架的整体细致构造及其与底层原生Javascript的联系,以便于开发者熟悉框架设计原理,更好地设计出自己的框架。
关键词:Javascript;前端框架;原型;Zepto
DOI:10.11907/rjdk.172716
中图分类号:TP319
文献标识码:A 文章编号:1672-7800(2018)004-0124-03
Abstract:In order to gain a better understanding of the framework design principles in front-end development, we take the front-end framework of Zepto as an example, use Javascript prototype chain, native Javascript and frame comparison method to analyze the framework of the overall design ideas. We have detailed analysis of the framework of the general structure, reconstruct Zepto object prototype, and encapsulate all the methods that will be used. Based on the micro-to-micro perspective, we present a framework of the overall structure and its relationship with the underlying native Javascript, which help developers familiarize framework design principles to better establish their frameworks.
Key Words:Javascript; front frame; prototype; Zepto
0 引言
近几年随着前端领域的迅速发展,出现了多种类型的框架[1],目前市场上的主流框架(库)有jQuery、Vue、React与Angular等。但这几种框架的代码量太大,架构体系也比较繁琐,所以本文选取一种成熟且经典的框架,即Zepto进行分析[2]。该框架虽然出现时间较早,但作为设计框架的例子进行分析是十分适合的。首先,其架构与当前热门的jQuery很相似;其次,其代码量简短,可方便进行更透彻的分析。而框架的所有内容都是对底层知识的封装,采用原生Javascript与其对比的方法进行分析,可起到事半功倍的效果[3]。
1 Zepto简介
Zepto在5年前是一款十分热门的框架,其应用领域在于移动端,与jQuery框架十分相似。Zepto框架大量参考了jQuery的API,简化了对部分浏览器的兼容,例如IE。因此,可以说它是为移动端量身打造的[4],但其核心模块只有不到一千行的代码,相对于jQuery一万多行的代码量,其无论是分析还是编写都方便许多。同时,它也是众多前端开发者分析框架对象的首选。
2 Javascript原型
在原生Javascript的知识体系中,上下文环境、作用域、原型链、同步与单线程是重点,也是难点。在介绍Zepto设计原理前,先对Javascript原型进行分析,这也是Zepto的设计基础。每创建一个新函数,都会根据一组特定规则为该函数创建一个prototype属性,该属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,该属性包含一个指向prototype属性所在函数的指针[10]。
图1展示了Person构造函数、Person原型属性以及Person现有两个实例间的关系。在此,Person.prototype指向原型对象,而Person.prototype.constructor又指向Person。原型对象中除包含constructor属性外,还包括后来添加的属性。Person的每个实例,如person1和person2都包含一个内部属性,该属性仅指向Person.prototype。也即是说,它们與构造函数没有直接关系[5]。因此,可以在构造函数的原型对象中定义公共的属性或方法,例如图1中的name、age、job和sayName,这些方法与属性是任何一个通过构造函数产生的实例所能共享的。此外,在每个实例中,还可以添加额外的属性与方法,这时添加的属性与方法是每个实例单独享有的[11]。
3 Zepto设计原理
先分析一个简单的html页面,代码如下:
var MYMp = MYM(‘p); //MYMp是数组
var MYMspan = MYM(‘span); //MYMspan是数组
通过API可以知道MYMp.addClass是一个函数,这是一般数组不具备的,在控制台输出MYMp instanceof Array为false,也验证了MYMp不是一个常规数组的实例。与通常遇到的不同,正如原型里提到的,通过函数new输出的内容,都会有个指针指向该函数的原型对象,而将原型对象重构后,即可获得大量所需的方法。Zepto正是采用该方式对原型对象进行了改造。因此,每一个看似数组的内容可以同时具备数组与非数组的方法。这也是Zepto的核心设计理念,即重定义原型对象内容[6]。
4 Zepto源码分析
Zepto框架主要架构如下:
varZepto = (function(){
var MYM, zepto = { }
//省略N行代码
function Z(dom, selector){
vari, len=dom?dom.length : 0
for(i=0; i
}
对于zepto.Z函数,代码如下所示:
function Z(dom, selector){
var i, len = dom ? dom.length : 0
for(i=0; i this[i] = dom[i] this.length = len this.selector = selector || ‘ } } zepto.Z = function(dom, selector){ return new Z(dom, selector) } MYM.fn = { //…多种属性 } zepto.Z.prototype = Z.prototype = MYM.fn 這里对构造函数Z进行了实例化,Z函数与之前提到的原型密切相关,将原型函数进行重构,会获得许多自定义的属性与方法。MYM.fn函数是Z函数原型的出处,里面封装了一系列原生Javascript的内容,将其与原生Javascript对比可发现,slice、each等方法都可以在原生方法中找到对应部分,同时考虑到兼容问题,整个原型对象即可完整呈现。至此,整个Zepto框架组合完毕,详细的属性方法可在API文档中查看。 5 结语 纵观互联网浪潮中的前端领域,其发展十分迅速,各种组件库、框架应运而生,因此前端也变得越来越复杂。但这一切变化都是建立在Html+CSS+Javascript上,而这些底层技术的变化相对缓慢[8]。本文分析了框架的设计原理与设计架构,将其中的封装方法与原生Javascript方法进行对比,并阐述了此类框架设计的核心要点[9]。当然,在分析过程中也存在一些不足,如没有将封装方法与原生方法进行一一比对,框架代码未能全部展现出来等,将在后续工作中进一步改进。 参考文献: [1] 王悦.基于Extjs4的Web前端框架设计与应用[D].青岛:中国海洋大学,2015. [2] 王保平.对JavaScript框架的再思考[J].程序员,2008(11):24. [3] 樊红珍.JavaScript框架jQuery和ExtJS的对比研究[J].现代计算机月刊,2011(1):23-24. [4] 李红.主流Javascript框架比较与分析[J].鞍山师范学院学报,2015(4):40-47. [5] 司徒正美.JavaScript框架设计[M].北京:人民邮电出版社,2014. [6] 欧查德,LM. JavaScript框架高级编程:应用Prototype、YUI、Ext JS、Dojo、MooTools[M].北京:清华大学出版社,2011. [7] 栗新雨.两款jQuery前端框架(DWZ和MiniUI)之比较[J].计算机光盘软件与应用,2013(20):276. [8] 姜艳.一种基于JavaScript框架的混合应用开发技术[J].网络新媒体技术,2016,5(4):59-64. [9] 代庆梅.浅析JavaScript MVC框架在Web开发中的应用[J].电脑知识与技术:学术交流,2014(4):2242-2245. [10] 彭敦陆,杜雪锋.基于Web服务的组件集成技术在客户关系管理中的应用[J].上海理工大学学报,2004,26(1):71-75. [11] 蒋伟良,徐福缘.ADO方案与胖客户环境下的交互HTML数据库设计[J].上海理工大学学报,1999(2):184-187. [12] JENSEN S H, MLLER A, THIEMANN P. Type analysis for JavaScript[J]. Lecture Notes in Computer Science, 2009,5673:238-255. [13] GUHA A, SAFTOIU C, KRISHNAMURTHI S. The essence of JavaScript[J]. Lecture Notes in Computer Science, 2015,6183:126-150. (责任编辑:黄 健)