chunpu / blog

personal blog render by jekyll
MIT License
51 stars 8 forks source link

即便是在现代浏览器中, 你也应该使用 jQuery #81

Open chunpu opened 9 years ago

chunpu commented 9 years ago

即便是在现代浏览器中, 你也应该使用 jQuery

近来各大浏览器都很好的支持了 es5, chrome 和 firefox 更是支持了部分 es6 功能, 有不少同行就表示不再需要 jQuery 了, 用 Vanilla.js 足以, 我书读得不多, 查了一下词典才知道这是个 joke, 就是说什么不用任何 javascript 框架的意思

以 winter 老师为首, jQuery 是这样被黑的

从jQuery谈库与框架的设计之优劣

设计优秀的 API 有什么特征?

诚然 winter 老师的水平是我的十倍百倍, 但没到 winter 老师的水平, 我还是会用 jQuery

相信大家在 jQuery 中主要用到这三个特性

$ 是一个 arraylike 的构造函数, 就像 NodeList 一样, 可以进行批量的元素操作

为什么我们不直接用 NodeList 呢, 因为 NodeList 也是 arraylike 对象, 不是数组, 要变成数组我们只能 Array.prototype.slice.call(NodeList), 可问题来了, 旧版 IE 不支持 slice.call(NodeList)

除了最基本的 .each .filter .map, jQuery 封装了更多其他的属性批量操作, 比如 .text .html .val

有些现代浏览器的 api 用起来还不如 jQuery

// 原生 javascript
Array.prototype.forEach.call(document.querySelectorAll('tag'), function(el) {
    el.classList.toggle('visible')
})

// jQuery
$('tag').toggleClass('visible')

winter 老师曾表示 jQuery 重载函数有9种, 基本包罗万象, api 设计的很差

有意思的是 jQuery 这么多重载, 在我眼里却只有一种

function $(val, box) {
    if (is.fn(val)) return $(doc).ready(val)
    if (!(this instanceof $)) return new $(val, box)

    this.length = 0

    if (!val) return

    if (is.string(val)) {
        if (-1 == val.indexOf('<')) {
            val = find(val, box)
        } else {
            val = parse.html(val)
        }
    }

    if (!is.arraylike(val)) val = [val]

    var len = val.length
    for (var i = 0; i < len; i++) {
        this[i] = val[i]
    }
    this.length = len
}

一句话描述就是 $(arraylike) => jQuery arraylike

完整代码见https://github.com/chunpu/min-jquery/blob/gh-pages/index.js

这里衍生一下, 为什么我们不用 Array 的子类来定义 $(util.inherits($, Array)), 同样是旧版 IE 的问题, IE6-8 的 数组 length 属性是不可变的

ajax

jQuery 的 ajax 有多好用就不谈了, 曾经我是知道怎么手写 ajax 的, 但用了 jQuery 之后我已经不会了

统一的事件管理

熟悉 jQuery 的朋友知道, jQuery 的事件是自己管理的, 用 jQuery 监听的事件本质上都是在元素上加一个 handler, 最后由 jQuery 内部完成事件的触发

那统一管理事件有什么好处呢, 抛开 namespace, return false, 批量 on 和 off 这些方便的用法, 最重要的是可测试, 比如一个点击操作, 你要做自动化测试, 恐怕要上 webdriver, 但 jQuery 不需要, 因为它可以 .trigger, 这样你可以很容易的写出测试

即便抛去这上面这些不谈, $ 也比 element.querySelectorAll 短太多了

有人说 jQuery 中 set 和 get 让人迷惑, set 通常是全部都 set, 而 get 只是对第一个元素, 其实这也很好理解, 这些 .attr .prop .css 都是由 $.access 控制的, 如果是 get 就返回第一个元素的值, 如果不是 get (可能是 set 也可能是判断) 就会对全部元素进行处理, 同时 set 会返回 this 来支持链式操作

winter 老师还表示, jQuery 太大了, 压缩后还要 97k, 我就写个 ajax 真的要引入这 97K 嘛, 我们不妨看看 underscore 这个 util 库, 哇! 压缩后竟然 16k 之多, 你只是个小小的 util 库额. 但真的要用 jQuery 却不想搞这 97k 咋办? 请使用 min-jquery, 支持 IE6, 只有20k(广告文本质暴露..)

你也许会说 现在流行的是 Angular, React, jQuery 已经落伍了, 这就错了, Angular, React 他们都是框架(framework), 而 jQuery 不过是一个库 (Libary), Angular 里面也内置了 jqLite

未完, 在床上一时兴起瞎写的, 话说你们 star 我私人博客干嘛, 4个 watch, 7个 star 要闹哪样

yutingzhao1991 commented 9 years ago

jquery 已经成为操作dom的标准,用着也挺好用的,就别折腾了。要是嫌大可以用 jqLite 或者 min-jquery :D

其实我只知道jquery的 $(selector).xxx

yolio2003 commented 9 years ago

通神的博客必须看啊,我也觉得jQuery依然好用! 自己写一个小小的 dom parser,很容易就可以让jquery 融合上双向绑定、component 等思想。 就是觉得file size有点大了,希望打散成更小的可组合模块 / 函数。