精华 Lo-Dash 与 Underscore,Prototype 与 jQuery,两段恩怨情仇
发布于 21 天前 作者 justjavac 381 次浏览 来自 分享

这几天更新我的之前写的 Chrome 插件 ChromeSnifferPlus 可以探测正在使用的开源软件或者 js 类库,两天的时间增加了 20 多个 js 库的检测,并重构了部分代码,将版本升级到了 2.x。

今天想增加 lodash 的检测代码,可犯了愁了。

打开 lodash 的主页,直接检测为 Underscore。

ChromeSnifferPlus

足足研究了半个小时,真是说来话长啊。


一场恩怨,一段纷争,一段历史。

在 javascript 领域,最难处理的就是浏览器兼容的 DOM 操作。这时 Prototype 框架最先引入了 $ 符号,凭借其便利的多平台兼容的 DOM 处理、Ajax 处理、以及一些辅助工具函数,受到开发者的青睐。后来 Ruby On Rails 崛起,并内置了 Prototype 库,从此 Prototype 一炮而红。

很快,这个 $ 被另一个框架所使用,就是我们熟知的 jQuery,同样也是操作 DOM,Ajax 处理。但是 jQuery 很快就超过了 Prototype 的锋芒。

现在很多前端开发者都不知道什么是 Prototype。也有部分开发者把 jQuery 当作 javascript。可见,前端大战以 jQuery 的完胜而告终。

无疑,在目前浏览器不完全兼容的情况下,jQuery 提供的 API 是操作 DOM 的最佳选择。

那么在一个没有 DOM 世界会是怎样的呢?

Node.js 的兴起把我们带到了一个没有 DOM 和 BOM 的世界。我们需要的是函数、库,我们要处理数字,处理字符串,处理数据…… 所有这些,jQuery 的 $ 没有提供,那谁提供了呢?答案就是 Underscore 的 _

这个库的名字叫 Underscore,而 Underscore 就是"下划线"的意思。Underscore 给开发者带来了什么呢?很酷的函数式思维。

当我们想把数组 ['left ', ' center ', ' right'] 中各个字符串元素两边的空白符去除,我们可以这样:

_.map(['left  ', ' center ', '  right'], function (s) {
  return s.trim();
});

在写前端代码的时候,Underscore 一直是我使用次数排名第二的库,第一是谁,当然是 jQuery 了。所以代码里面满屏都是 $_

就像 jQuery 替代了 Prototype 一样,Underscore 也迎来了挑战,那就是 lodash。Lodash 也使用 _ 符号,而且 Underscore 的所有函数 Lodash 全部包括,不仅如此 Lodash 还增加了很多 Underscore 没有的函数。更可气的是,只要 Underscore 添加了啥新功能时,Lodash 都会及时覆盖更新,以维护它一如既往超集的地位(要脸不)。真正的杀手锏是,Lodash 函数的性能是 Underscore 的四五倍。

file

今天五月份,Underscore 的创造者 Jeremy Ashkenas 在一条 Github issue 中向 Lodash 的创造者 John-David Dalton 表明合并两个库的意愿。

然而社区的意见偏向于,lodash 是唯一选择。

Babel 的贡献者 James Kyle 认为,现状不会改变。“所有的一切会一如既往地发展着,Lodash 会缓慢更新,但是一定会彻底替代 Underscore”。

如果看看 NPM 的 most depended-upon packages,Lodash 名列第 1,而 Underscore 命令……那个……第 2 或者 第 4。(谁能告诉我这个是横着看,还是竖着看)

上个月的下载量,Underscore 为 1 千多万,而 Lodash 则是 2 千多万。而 jQuery 呢,不到 1 百万。

言归正传,继续回到我的插件 ChromeSnifferPlus 上来。既然 lodash 是 Underscore 的超集,那就有办法区分了。

之前的判断都是通过特性判断,也就是:如果支持某特性,或者包含某个函数,则认为加载了某个库。比如判断 jQuery:

window.jQuery && jQuery.prototype && jQuery.prototype.jquery

如果页面没有使用 jQuery 上面代码返回 undefined,如果使用了 jQuery 则返回 jQuery 的版本号。如果在当前页面的控制器运行此段代码,返回 "2.1.1",因为 segmentfault 使用了 jQuery,并且版本是 2.1.1。果然是开发者的社区,不需要兼容老旧的浏览器。

所以之前我的判断代码是 window._ && _.VERSION,结果误把 lodash 检测为 Underscore 了。

既然是超集,我们可以找一个特性,这个特性 lodash 支持,而 Underscore 不支持,以此区分。随便找一个函数,比如 attempt,因此我们可以这样检测:

检测 lodash:

window._  && typeof _.attempt === 'function' && _.VERSION

检测 Underscore:

window._  && _.attempt === undefined && _.VERSION

不过,是时候放弃 Underscore,使用 lodash 了。

untitled1.png

10 回复

社区还是有合并想法的 https://github.com/underdash/underdash, 只是还没有定论。

昨天刚好在知乎看了

赞啊 顺便说,看页面结构,most depended-upon packages 貌似是横着排的。。 还有还有,你的函数式思维不够彻底。。。 我自己感觉这样更好:

_.map(['left ', ’ center ‘, ’ right’], _.trim);

开源产品的战争

有意思啊!

我想问,图里的Lazy.js是啥,为啥木有讲到,效率很高的样子,为啥不用呢?

无意中发现了underdash这个库,笑死我了

回到顶部