从jQuery谈库与框架的设计之优劣
jQuery是业内知名的javascript框架,它的实现和设计可以说代表了javascript界最高的水平,本文试从四个方面来以jQuery为例总结库与框架设计的原则和优劣判断。
解决问题
首先请看一个我实现的框架,我把这个库称为四则运算。
- function add(a,b) {
- return a+b;
- }
- function mul(a,b) {
- return a*b;
- }
- function minus(a,b) {
- return a-b;
- }
- function div(a,b) {
- return a/b;
- }
这个库的API简洁优美,实现的更是优雅无比,它把四则运算统一成了函数形式,使得我们的开发更加方便。最强大的是,这个做法使得四则运算支持函数式编程,比如:
- function acc(a,b,f) {
- var jieguo = a; //http://weibo.com/2178807082/zk1kOcMPU
- for(var i = 1; i<b; i++) {
- jieguo = f(jieguo,a);
- }
- return jieguo
- }
这样,通过acc函数,我们可以轻易实现n次方运算,这正是函数式编程之美。
举这个例子是为了告诉大家,一个框架/库其实可以不需要解决任何问题——只要你会乱用概念、自吹和哄骗新手就够了。
下面我们来看看一个非常成功的框架——jQuery解决的问题,让我们来看看jQuery首页的"Brief Look"中给出的第一个例子。
- DOM Traversal and Manipulation
- $( "button.continue" ).html( "Next Step..." )
嗯,没错,jQuery希望帮助我们解决遍历DOM的问题,如果没有jQuery,我们大概要写一个traversal函数了。
- function traversal(node, f) {
- f(node);
- if(node.children.length) {
- for(var i = 0; i<node.children.length;i++)
- traversal(node.children[i],f);
- }
- }
- traversal(document.body,function(element){
- if(element.tagName=="button" && element.className.match(/continue/)) {
- element.innerHTML = "Next Step...";
- }
- })
traversal这个函数真的是超麻烦不是么?竟然有175个字符呢!使用起来也有166个字符,用了jQuery之后,只要45个字符就可以搞定呢!好神奇!
好吧原谅我刚才把思维模式切换到了"write less, do more"模式,jQuery正是通过一个字符一个字符地节约程序员的工作量来达到这一伟大目标的。
压缩后仍达97k的jQuery竟然帮助我们少写了这么多代码,好神奇啊啊啊!这正是库/框架设计的要点,那就是"没有问题创造问题也要解决问题!"
命名
命名问题对于库/框架来说,尤其重要。
总的来说,如同正统程序员那样追求命名的易读、易懂、与原生一致的话,你的库/框架不会有任何出彩的地方。
好的库/框架,命名有几个原则,第一个原则,就是要有厚重的历史感。
在80年代,因为C语言支持的变量名最长为8字节,聪明的程序员们使用了一种缩写方式,保留发音的轻辅音字母,省略元音字母和部分浊辅音字母。
比如:
- button=>btn
- text=>txt
- search=>srch
- fuck=>fk
- click=>clk
- double=>db
没错,这样虽然省略了字母,但是英文好的人仍然可以读出单词来,而现在,虽然我们完全没有这种需要,我们也可以为了给新人以距离感和绝对的震慑而使用这种命名。
还有一种历史上的命名方式:匈牙利命名。
匈牙利命名使用简写的类型作为变量的前缀,比如
- iCount表示int类型的count
- szText表示字符串类型的text
- bIsNumber表示布尔类型isNumber
- dRate表示表示双精度浮点类型rate
是不是看上去很酷?值得一提的是,sz表示以0结尾的字符串,这是C语言中字符串的实现方式,JS中完全不是这样实现的字符串,所以这样用可以大大提升你在新手中的地位,他们做梦也猜不到sz是字符串的意思。
另外,其实js是弱类型语言,变量根本就跟类型不是绑定的。
除了历史之外,特殊符号也是我们的首选,在javascript中,$美元符号和_下划线是非常棒的选择。这当中的代表作当属jQuery和underscore.
jQuery的$使用也并非原创,先行者是prototype.js,这也让jQuery的做法具有相当厚重的历史感。同时,美元符号比下划线强的地方 是,美元符号还具有吉祥如意的寓意,咱们写代码的,出来不就是混口饭吃,如果代码经常出现美元,一定会给我们带来很多财运的。
占领这些特殊符号可以让别的框架无符号可用,当年jQuery和prototype.js争霸之时,jQuery就被迫搞出来了 noconflict——尽管基本没见过有人用过,毕竟要把满篇的$改成jQuery还是颇费体力的,多数人会选择放弃一个库。(什么你说根本不需要替 换?直接在外面套个闭包就能解决问题?醒醒吧亲,能同时用俩带$库的工程师怎么可能会那种高级玩意儿啊,人家都是实践派好吧?)
不过大家不要伤心,虽然没有了$和_可以抢,ES5为我们带来了更多奇形怪状的、键盘轻易都输入不来的标示符可用字符。我首先要推荐的是两个零宽字 符<zwnj>和<zwj>,这俩字符一个是连接符,一个是非连接符,它们的厉害之处在于,不可见,通过这俩字符,你可以制造出 假的$来。
请看以下代码:
var $ = 1;
估计你做梦也想不到这变量其实是$\u200D(<zwj>)吧......
通过\u200D和\u200C的组合,可以制造神奇的代码出来,你的用户一定会交口称赞你的魔法代码的!
不止如此!更多奇怪的字符等你挖掘!
接口设计
除了命名,接口设计也是框架的核心之一。
那些平庸的框架会用"单一职责"原则来设计接口:不论是类还是函数,一个只做一件事,而且跟命名 中所说的完全一致。
Noooooooooooo ! 这也太无趣了!
我们来看看jQuery的$有多少种用法!摘自官方文档:
- jQuery( selector [, context ] )
- jQuery( element )
- jQuery( elementArray )
- jQuery( object )
- jQuery( jQuery object )
- jQuery()
- jQuery( html [, ownerDocument ] )
- jQuery( html, attributes )
- jQuery( callback )
没错!这个函数(jQuery就是)居然有9种重载!而且重载中最少包含了3种毫不相干的使用方法!一段时间里,我曾经在面试中问所有声称自己熟悉jQuery的面试者这个函数有多少种用法,可以答上三种以上的仅有1人,而没有人答出来过超过5种!
可以说,$在jQuery使用者的眼里就是一个神!你能想到的事情它都能做!在可以预见的将来,相信jQuery会结合人工智能,做到不论你想实现任何功能,都只需要写同样的代码:
- $();
怎么样,看清楚接口设计的原则了么?那就是:尽量把功能加到以前的接口上,通过加参数、区分参数类型来添加功能,不论它们有没有联系,也不论API的名称是什么!哦...... 对了这个应该结合上文提到的命名,请使用没有任何意义的魔法变量名!
耦合
你可能常常听到一些旧时代的程序员讲,程序必须"高内聚、低耦合"。然而,这个说法具有极大的误导性。
我们先来看看jQuery的事件绑定:
- var hiddenBox = $( "#banner-message" );
- $( "#button-container button" ).on( "click", function( event ) {
- hiddenBox.show();
- });
- 假如我不想使用选择器,只想要绑定事件到一个DOM元素上怎么办呢?答案是,你要首先把他变成一个jQuery对象才行
- $(document.querySelector("#button-container button")).on( "click", function( event ) {
- hiddenBox.show();
- });
接下来我们来看jQuery的ajax部分:
- $.ajax({
- url: "/api/getWeather",
- data: {
- zipcode: 97201
- },
- success: function( data ) {
- $( "#weather-temp" ).html( "<strong>" + data + "</strong> degrees" );
- }
- });
假如你仅仅想要使用$.ajax这个功能,不想使用选择器等功能怎么办呢?答案很简单:像你需要使用全部功能一样,在页面引用仅有97k的jQuery,然后使用$.ajax。
从这个例子中我们可以看出,耦合对于一个库的重要性:耦合让你那些不太被人接受的功能,跟着受欢迎的功能一起被强制使用,这样,用户就会逐渐被强奸,逐渐变得认为理所当然,这正是jQuery能够成为"事实标准"的奥秘。
从jQuery谈库与框架的设计之优劣的更多相关文章
- 【安富莱】V6,V5开发板用户手册,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔(2019-11-04)
说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.本次工程延续以往的代码风格,从底层BSP驱动包到应用代码,变量命名,文件 ...
- 【安富莱】STM32H7用户手册发布,重在BSP驱动包设计方法,HAL库的框架学习,授人以渔,更新至63章(2019-07-21)
说明: 1.本教程重在BSP驱动包设计方法和HAL库的框架学习,并将HAL库里面的各种弯弯绕捋顺,从而方便我们的程序设计. 2.由于是基于HAL库的文档,所以不限制H7系列,其它F1,F2,F3,F4 ...
- jquery源码分析(二)——架构设计
要学习一个库首先的理清它整体架构: 1.jQuery源码大致架构如下:(基于 jQuery 1.11 版本,共计8829行源码)(21,94) 定义了一些变量和函数jQu ...
- [连载]《C#通讯(串口和网络)框架的设计与实现》-1.通讯框架介绍
[连载]<C#通讯(串口和网络)框架的设计与实现>- 0.前言 目 录 第一章 通讯框架介绍... 2 1.1 通讯的本质... 2 1 ...
- 11个很棒的 jQuery 图表库
如果你曾经使用过任何类型的数据,你应该知道阅读一排排数据的痛苦.通过所有这些数据弄清楚他们的意思是非常不容易的.可视化对于解决这个问题起到了重要的作用.可视化降低了数据阅读的难度,帮助决策者获得可操作 ...
- jQuery多库共存处理
jQuery多库共存处理(来自慕课网) 多库共存换句话说可以叫无冲突处理. 总的来说会有2种情况会遇到: 1.$太火热,jQuery采用$作为命名空间,不免会与别的库框架或者插件相冲突. 2.jQue ...
- jQuery Mobile与QUI框架的异曲同工之处
最近一直在研究jQuery Mobile框架,这是jQuery的官方移动版UI框架,专门用来开发手机与平板电脑方面的应用.结果越来越觉得它和我的QUI框架的开发思路非常相似,很多地方都有异曲同工之妙. ...
- NHIBERNATE的简单框架的设计
NHIBERNATE的简单框架的设计 上次的 NHibernate的Session管理策略和NHibernateHelper 发布并提供下载,给NHibernate刚入门的同学们带来很多便利. 最近有 ...
- 基于jquery开发的UI框架整理分析
根据调查得知,现在市场中的UI框架差不多40个左右,不知大家都习惯性的用哪个框架,现在市场中有几款UI框架稍微的成熟一些,也是大家比较喜欢的一种UI框架,那应该是jQuery,有部分UI框架都是根据j ...
随机推荐
- 转CentOS — MySQL备份 Shell 脚本
http://www.cnblogs.com/bruceleeliya/archive/2012/05/04/2482733.html 使用 mysqldump 备份数据库,通过 FTP 上传到备份服 ...
- Android 轻松实现语音识别
2010-11-12 17:01:51 标签:休闲 职场 Android 语音识别 移动开发 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任 ...
- page_address()函数分析
由于X86平台上面,内存是划分为低端内存和高端内存的,所以在两个区域内的page查找对应的虚拟地址是不一样的. 一. x86上关于page_address()函数的定义 在include/linux/ ...
- JSON入门之二:org.json的基本使用方法
java中用于解释json的主流工具有org.json.json-lib与gson.本文介绍org.json的应用. 官方文档: http://www.json.org/java/ http://de ...
- Adobe推出HTML5动画设计工具Edge
HTML5和Flash,是敌对?是共存? 虽然Flash如今依旧牢牢占领着网络动画的大半江山,但这样的状况终将会被改变. 那么,Edge的推出是否意味着Adobe将放弃和屈服于Flash与HTML5之 ...
- CXF+Spring+JAXB+Json构建Restful服务
话不多说,先看详细的样例: 文件文件夹结构: web.xml <?xml version="1.0" encoding="UTF-8"? > < ...
- Python 字典 in 操作符
描述 Python 字典 in 操作符用于判断键(key)是否存在于字典(D)中,如果键在字典中返回True,否则返回False. 在Python2中还可以使用 has_key() 方法,官方文档推荐 ...
- POJ 2299:Ultra-QuickSort
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 39397 Accepted: 14204 ...
- ES6 class setTimeout promise async/await 测试Demo
class Person { async getVersion () { return new Promise((resolve, reject) => { setTimeout(functio ...
- js替换iframe的内容
使用如下方法可以替换页面中iframe里面的内容: for (var i=0; i<window.parent.frames.length; i++) { //window.parent.fra ...