1.2 器械迭代史:版本演进与选型 最初,jQuery 只是一个叫 "Selection" 的实验品,作者 John Resig 想解决的事很朴素:同一份选择器代码,别在每家浏览器里跑出不同的结果。上一节拆开了手术台的构造,这一节看它的出厂批次——版本从何而来、每一代改了什么、以及今天接手项目时该如何选型。版本史不是年表背诵,而是排错时的对照表:老项目里那些"为什么这个方法没了"的疑问,答案全写在演进节点上。 本节摘要:jQuery 1.x 兼容老浏览器并持续打磨 API;2.x 砍掉旧 IE 支持、瘦身换速度;3.x 对齐 ES6 之后的语言习惯,AJAX 返回 Promise、修复大量边缘行为。选型原则:新项目用 3.x 最新稳定版,兼容 IE 的存量项目锁在 1.12 或 2.
最初,jQuery 只是一个叫 "Selection" 的实验品,作者 John Resig 想解决的事很朴素:同一份选择器代码,别在每家浏览器里跑出不同的结果。上一节拆开了手术台的构造,这一节看它的出厂批次——版本从何而来、每一代改了什么、以及今天接手项目时该如何选型。版本史不是年表背诵,而是排错时的对照表:老项目里那些"为什么这个方法没了"的疑问,答案全写在演进节点上。
本节摘要:jQuery 1.x 兼容老浏览器并持续打磨 API;2.x 砍掉旧 IE 支持、瘦身换速度;3.x 对齐 ES6 之后的语言习惯,AJAX 返回 Promise、修复大量边缘行为。选型原则:新项目用 3.x 最新稳定版,兼容 IE 的存量项目锁在 1.12 或 2.2,并配 Migrate 插件做升级体检。

三条线的分水岭都由外部环境推动。1.x 时代浏览器混战,jQuery 最大的价值就是"写一份代码,到处行为一致";等到旧版 IE 退出舞台,2.x 果断砍掉兼容层换取体积与速度;再往后,语言本身补齐了 querySelectorAll、fetch、classList 这些拼图,3.x 的任务就从"填浏览器的坑"转向"让 API 更符合现代直觉"。
1.x:地基与全盛。 1.7 是个值得记住的节点——此前绑定事件有 bind、live、delegate 好几套入口,容易用混,1.7 把它们统一成 on 与 off,本教程第 4 章只教这一对。1.9 做了 aggressive 清理:live、toggle、$.browser 等一批老接口被移除,大量老项目升级到 1.9 后"代码报错但不知哪里变了",Migrate 插件正是为此而生——它会把你用到的已废弃接口在控制台逐条点名。
2.x:第一次减重。 删掉旧 IE 支持后,体积明显缩小,内部也甩掉了大量分支判断。对当时的项目来说,升级 2.x 的收益是纯性能,代价是放弃旧浏览器用户。
3.x:对齐现代。 变化集中在三处。其一,$.ajax 返回标准 Promise,可以接 then 与 await,与 fetch 风格合流。其二,行为修正:动画队列、.data() 的驼峰命名处理、.show() 与 .hide() 对样式的还原方式都做了更合理的重写——这类修正在 2.x 里升级可能引起老代码行为漂移。其三,安全维护持续至今,若干涉及 HTML 注入的漏洞在 3.5 及之后的版本里被修复,这是老版本最该升级的硬理由。
同一版本号通常有三种发行形态,差别只在"给谁看":
| 形态 | 特征 | 适用场景 |
|---|---|---|
| 未压缩版 | 带完整注释与可读变量名 | 本地调试、想读源码学习 |
| 压缩版 | 变量名缩短、去注释,体积小得多 | 生产环境上线 |
| slim 版 | 在压缩版基础上再去掉 AJAX 与效果模块 | 只用选择器与事件的项目 |
slim 值得多说一句:如果你的页面只用 jQuery 做选择器和事件绑定,动画交给 CSS 过渡、请求交给原生 fetch,slim 能再省下可观的体积。反过来,老项目若大量依赖 $.ajax 的完整选项,换 slim 会直接报函数未定义。
引入方式上,生产环境推荐固定版本的压缩包本地化部署或可靠 CDN——固定版本号能避免上游静默升级带来的行为漂移;调试期换未压缩版,报错栈才看得懂。
拿到一个老项目,按这个顺序判断:
// 第一步:看现状 console.log($.fn.jquery); // 打印当前版本,比如 '1.7.2' // 第二步:分诊 // - 1.x 且需要兼容 IE:留 1.12,不再动,只做增量审查 // - 1.x 但只跑现代浏览器:升 3.x,先挂 Migrate 跑全量回归 // - 2.x:同上,升 3.x 通常平滑 // - 已是 3.x:跟进最新补丁版,尤其别停在 3.5 之前
升级的具体步骤与回归清单在第 7 章的迁移一节展开,这里先记住原则:跨大版本升级是手术,不是换件衣服——先让 Migrate 把废弃用法全部报出来、修完、跑通核心流程,再撤掉拐棍。
今天起一个全新项目,选择 jQuery 之前值得先问:还需要它抹平什么?选择器、类名、事件、请求在原生 API 里都有对应物,兼容性问题主要集中在老 IE 的日子已基本结束。jQuery 依然值得上的场景是:存量代码深度绑定、团队熟它的心智模型、或插件生态恰好覆盖需求。这个判断题会在第 7 章的对照表里给出完整的打分维度;本节你只需要带着"版本决定能力边界"的意识进入下一章。
$ 太好用了,好到别的库也想抢。老页面上常同时挂着 Prototype、MooTools 这类同代类库,它们同样占用 $ 这个全局名——后加载者会覆盖先加载者,谁的 $ 生效看加载顺序,这是当年最典型的"静态资源打架"。jQuery 给出的解法是把 $ 交出去,只保住全名:
jQuery.noConflict(); // $ 归还给之前的占有者,jQuery 全名仍可用 // 写法一:全名上阵 jQuery('#queue').addClass('busy'); // 写法二:ready 回调的形参——把 jQuery 传进去当局部 $ jQuery(function ($) { $('#queue').on('click', '.item', handler); // 这个花括号里 $ 依旧归 jQuery }); // 写法三:起个短别名,全文件统一 var jq = jQuery.noConflict(); jq('#queue').hide();
三种写法里最推荐写法二:作用域只覆盖初始化代码,模块外零污染,且不强迫全文件改风格——第 7 章插件规范里"立即执行函数把 jQuery 当参数传入",用的正是同一个思路。极端形态 noConflict(true) 连 jQuery 全名也一并让出,用于同一页面挂两个不同版本的 jQuery(能救急,但属于脏手术,不到万不得已别做)。
顺带一个排错经验:症状是"页面上半段 jQuery 好使、下半段报 undefined",八成是中间又加载了占 $ 的库。控制台敲 jQuery === $ 一验便知——返回 false 就是让位仪式发生过,按写法二或三改写即可。
$.fn.jquery 一行代码即可确认项目的版本,是接手老项目的第一步。器械选定、开机完成,下一章进入手术台的核心科目:用选择器精准定位。