jQuery 为什么优秀兼谈库与框架的设计[转]

2021-05-04 05:27

阅读:419

标签:入口   drop   需求   相关   col   i++   def   grunt   做什么   

文章转自:https://github.com/lifesinger/blog/issues/114

从 @wintercn 的这篇文章说起:从 jQuery 谈库与框架的设计之优劣

先去读一读哦,不长的,winter 写得很幽默。

好了,看下文。

解决什么问题

拿 winter 的代码入手:

function traversal(node, f) {
    f(node);
    if(node.children.length) {
        for(var i = 0; i)
            traversal(node.children[i],f);
    }
}

traversal(document.body,function(element){
    if(element.tagName=="button" && element.className.match(/continue/)) {
        element.innerHTML = "Next Step...";
    }
})

这段代码很酷,看见了递归没?还有传说中的函数式编程!也不长,只有 166 个字符。考虑 jQuery 那庞大的 97K 代码,完全可以自己写啊,真心用不着什么类库。

可是,各位看官,在中国,有两种东西需要小心:一是 CCAV 的新闻,二是程序员的代码。你信前者就幸福了,后者嘛,请看:

尼玛,winter 坑我,复制过来的 traversal 方法工作有点不正常呀

为了节约笔墨(精彩在后面),先不说 children 的坑(不说是因为 winter 刚好绕过去了),来说说下面这个:

button class="continued">

这可不是故意挑刺,我们在讨论类库哦。上面的 button 也会被 traversal 命中。好吧,我帮 winter 修改下:

traversal(document.body,function(element){
    if(element.tagName=="button" && element.className.match(/(?:^|\s)continue(?:\s|$)/)) {
        element.innerHTML = "Next Step...";
    }
})

修改后,正则看起来很酷。师兄下次 review 代码时,应该会觉得我技术有进步,加薪、晋升有望了……

继续节约笔墨(精彩在后面),不说代码的优化空间。只想问呀,这么一个简单的功能,值得如此折腾吗?为何不用一行搞定:

$( "button.continue" ).html( "Next Step..." )

好了,各位看官,你还同意 winter 说的 jQuery 是 “没有问题创造问题也要解决问题” 吗?

调侃结束,言归正传。jQuery 解决什么问题,jQuery 能做什么,来看官网:

jQuery is a fast, small, and feature-rich JavaScript library. 
It makes things like HTML document traversal and manipulation,
event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers.
With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

 

云译一下:

jQuery …… 让 DOM 操作简单 …… 跨浏览器 ……

翻译有直译、意译、神译,但在云时代,得用云译。诠释如下:

  • jQuery 是 DOM 操作类库,非常专注。 这很重要很重要。正是这种 专注做小 的心态,让 jQuery 在 DOM 操作领域所向披靡。这比野心勃勃想着做大的 Prototype、YUI、Dojo 等不知强多少呢。jQuery 的流行证明了专注的力量。找老公也可以用 jQuery 去衡量。
  • jQuery 真的很专注。 常见的 each,尼玛的 Deferred 等看起来和 DOM 无关的东东,实际上跟 DOM 方法的实现很有关系,暴露出来挺有用,因此才暴露。此外,与 DOM 操作实现无关的 cookielocalStorage 等等,jQuery 一律不提供。(注:个人觉得如果这些内部方法不暴露,只暴露与 DOM 操作相关的方法,jQuery 会更完美。注2:别跟我较真说动画和 Ajax 不是 DOM 操作。)
  • jQuery 非常关注用户。专注于 DOM 操作及其兼容性,让普通用户包括设计师都可以快速写出代码,这是 jQuery 的巨大价值。

预测:苏宁电器会改名叫苏宁云商,但 jQuery 不会改名为 jLibrary。和 jQuery 同样专注的还有 Evernote、Amazon、Dropbox 等等牛逼的东东。

(精彩已讲完,下面可以不看。 在类库界,解决了 What,解决了定位问题后,基本上已经决定了生死存亡。 至于 How,也重要但往往不是关键。最近看 Grunt 类库,也有同感。)

也谈命名

命名非常重要。比如决定 winter 牛逼的,不是 1024,而是 winter 这个名字。

不过没看懂 winter 说什么,因为 winter 说的和 jQuery 没什么关系。可能跟 jQuery 的早期版本有关系,但任何事物都会有历史局限性,就如我就一直期待传送门,但不能嘲讽当代的汽车。

至于 $ 的选择,这就如 码农屌丝 等词汇一样,winter 好像也经常用,并不反感。$ 的选择也像 QWERT 键盘,或者系统中用 ~ 表示 Home 目录一样。为什么很少见 *nix 用户不爽 ~ 呢?

不评论了。要谈命名,不如谈 jQuery 的方法名,简洁明了。YUI3 等类库抄得不亦乐乎,这是一种认可与致敬。

接口设计

泛义上讲,完全同意 winter 的说法。我也非常讨厌一个方法职责不清、身兼数职。比如 RequireJS 里,最让我不能忍受的重要原因之一就是,天杀的 require 方法一会是全局方法,一会是函数变量,一会是云,一会是风……

不过, 谈任何设计,都离不开场景。

jQuery 是 DOM 操作类库。jQuery 首要要解决的是: 如何高效方便地操作 DOM? 在这个真实需求下,jQuery 选择了一句话:

找到 DOM 元素,然后再操作、继续操作。

上面这句话,不是 jQuery 凭空设计出来的,而是千万前端工程师们在写代码时实际上会干的事情:

var foo = document.getElementById("foo");

foo.setAttribute("data-bar", "bar");
foo.innerHTML = "...";

上面的代码挺不错的,但有坑。jQuery 将上面这种常见代码,通过链式操作简化成了:

$("#foo").attr("data-bar", "bar").html("...");

这就如我们一般不会说:

我是 winter
我喜欢编码
我喜欢妹子

而会说:

我是 winter,喜欢编码,也喜欢妹子。

至于 getter 和 setter 的统一,可以类比:

var host = { a: "a" };

// 获取值
alert(host.a);

// 设置值
host.a = "aa";

别跟我说一定要:

var host = {
  a: "a",
  getA: function() { return this.a; },
  setA: function(val) { this.a = val; }
}

不直接通过属性,而通过方法来搞定 getter 和 setter,个中缘由 winter 比我更清楚,有兴趣的可以看:defineProperty

其实上面说的跟 winter 反驳的没什么关系,winter 主要反对职责不单一。不过,职责不单一的方法,在 jQuery 里有,但并不多。至于 $ 的功能,这是入口方法,为了用户的便利性, 适当放下程序员的完美情节,个人觉得是一种 面向用户的权衡。很多产品也如此,在屌丝用户看来很糟糕,但普通用户还真喜欢,因为方便。

耦合

举例子来说说:

  1. YUI3 最初的理念中,有一个很重要的是 颗粒化。颗粒化使得 winter 可以单独调用 ajax 模块。然而,YUI3 发展至今,虽然颗粒化极细,但你若去看使用 YUI3 的页面,稍稍 YUI().use("node") 一下,加载过来的文件大小就超过 jQuery 了。
  2. 颗粒化必须考虑颗粒的大小、范畴。 在 DOM 操作领域,能够保持功能与 jQuery 近似,大小又比 jQuery 小的,目前我好像还从来没有看到过。除非把定位缩小,比如只支持 webkit,砍功能后,才有可能比 jQuery 更小。同等功能下,能做到 jQuery 这么优秀的 DOM 操作类库,如果你发现了一定要告诉我。
  3. 一个文件。 能用一个文件解决的,不用两个文件来做。超过一个文件就意味着依赖关系的管理。这里拿老赵的 Wind.js 来说,够屌丝了,但普通用户真不愿意去搞清楚那几个文件怎么引,还要分谁先谁后,天哪。所以后来 Wind.js 也有了 aio 版本(All in One)。方便用户,而不是满足自己。
  4. 历史与未来。 当然,上面说了这么多,但场景在飞速变化。比如 IE6 的市场份额在国外已经到了可以忽略的地步。场景的变化,使得 jQuery 开始朝向 2.0 发展。Animation 和 Ajax 等模块在设想中也都可以独立出来,还有很多很多变化。但最大的变化,个人觉得不是理念更先进了(模块化老掉牙了),而是 顺势而为。这个“势”是场景的变化。设计架构的演变,离不开场景。场景的变化经常推动着设计的进化。很多公司的架构之所以牛,并非牛人使然,而是公司业务场景的需要。快跑题了,这个另一个蛮有意思的话题……

写在最后

jQuery 的专注,不三心二意, 非常有利于生态圈的形成。君不见,jQuery 社区目前就是前端界的阿里巴巴呀,winter 你来一淘了,应该认可阿里的大方向哦。反观 YUI3 等框架,不是京东又是什么呢?

最后,来点煽情的。jQuery 在我心中,是一尊女神。她温柔、细腻,她火辣、傲娇,一定会有人骂她,但真了解她的,会爱上她。

 

jQuery 为什么优秀兼谈库与框架的设计[转]

标签:入口   drop   需求   相关   col   i++   def   grunt   做什么   

原文地址:https://www.cnblogs.com/jun1019/p/12116968.html


评论


亲,登录后才可以留言!