> For the complete documentation index, see [llms.txt](https://coffe1891.gitbook.io/frontend-hard-mode-interview/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://coffe1891.gitbook.io/frontend-hard-mode-interview/id-3/1.-zong-he-bi-jiao/3.1.1.md).

# 叁.1.1 jQuery过时了吗？

## 叁.1.1.1 jQuery带来的好处

![jQuery之父 John Resig](https://1680353414-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnlixiOMXyluGpXDGGs%2F-M8T-hReKKWTFmT5TzeC%2F-M8TC-lSnEtwfn76tG64%2Fjohn-resig.jpg?alt=media\&token=cae24f41-ac38-425e-ba62-6fb630ab258b)

John Resig在2006年发布了jQuery第一版，十几年过去了，截止2019年6月的统计，jQuery仍然被全球最活跃的前1000万个网站中的73%所使用，其影响力之大可见一斑。jQuery作为最流行的JavaScript库，其诞生之初便为前端开发带来了以下好处：

### **1. 解决了当时浏览器兼容问题**

jQuery诞生时的2006年，微软IE6在浏览器市场里所占份额最大。这个“傲慢”的浏览器自成一套，很多API没有遵从W3C标准，因此造成各种兼容问题（出于浏览器大战时的竞争策略的考虑，微软没有把遵从W3C标准放在重要的位置）。调用某些相同功能的DOM API，IE6与其他浏览器比如Firefox、Opera、Safari在语法上有差异。这让前端工程师经常要写两份甚至多份代码，不胜其苦。最烦恼的还不止于此，微软自己的浏览器，若版本不一样居然也有兼容性问题，比如IE6的代码居然也不兼容IE7、IE8！此时jQuery出现了，它及时、有效地解决了这些问题，让前端工程师只需要写一份代码，无须担心兼容性。这也是jQuery大受欢迎的最重要的原因。

```javascript
// 过去如果不用jQuery，监听事件（兼容IE6）要这么写
if (button.addEventListener)  
  button.addEventListener('click',fn);
else if (button.attachEvent) { 
  button.attachEvent('onclick', fn);
}else {
  button.onclick = fn;
}

// 但是如果用jQuery只需要这么写
$(button).on('click', fn)
```

### **2. 发明了一种便捷的DOM操作方式**

jQuery 极大地简化了对元素选择：

```javascript
// 如果你想获取 .nav > .navItem 对应的所有元素，用 jQuery 是这样写的
$('.nav > .navItem')

// 在 IE 6 上，你得这么写
var navItems = document.getElementsByClassName('navItem')
var result = []
for(var i = 0; i < navItems.length; i++){
  if(navItems[i].parentNode.className.match(/\bnav\b/){
    result.push(navItems[i])
  }
}
```

例如，原来你要修改样式，原生JavaScript是这么写的：

```javascript
var dom = document.getElementById('coffe1891');
dom.style.color = 'blue';
```

用上jQuery后，一行搞定：

```javascript
$('#coffe1891').css('color', 'blue');
```

### **3. 轻松实现动画效果**

例如，我们需要把 一个`<div>`元素移动到左边，直到left属性等于1891像素为止。 使用jQuery，我们可以这么写：

```javascript
$("div").animate({left:'1891px'});
```

### **4. 封装了极易使用的Ajax**

本书[壹.2.13已有一段用原生的JavaScript实现ajax请求的代码](/frontend-hard-mode-interview/id-1/2.-he-xin-gai-nian/1.2.13.md#ajax)，相当的复杂。而 用上了jQuery后，简洁了不少！如下所示：

```javascript
$.ajax({
    url:"www.xxx.com/coffe1891",
    success:function(result){
        //dosomething
    }
});
```

总而言之，jQuery作为一个JavaScript&#x5E93;**，**&#x8FD9;个库里有很多函数可以简化你的DOM 操作，提供一些特效功能等等。它帮我们封装好了各种不会写、不想写、没时间写的代码，以极其人性化/易懂的API的方式提供出来，让我们通过简单的调用就能直接实现丰富的功能。

## 叁.1.1.2 现在已经有了比jQuery更好的方案

随着时代的发展，毕竟也有十几年过去了，前端开发有了很大的变化。针对前面提到的jQuery的4点好处，现在也已经有更好的替代方案。

### 1. 针对兼容性

现在主流浏览器拥抱W3C标准，因此浏览器之间的兼容性做得越来越好。兼容性做得极差的浏览器IE6已经成为历史，甚至在绝大多数生产环境中连IE8都可以不用考虑，况且还有Babel.js这样更轻量级的库存在。

### 2. 针对DOM操作

jQuery能够快速选取DOM结点，这个无疑是jQuery受欢迎的一个重要的原因。但是就目前情况来说，这个优势已经没有了，为什么呢？有两个已经成为W3C标准的API：`document.querySelector`和`document.querySelectorAll`，这两个API可以通过传入css选择器形式的字符串，以匹配到预期的DOM节点，而且基于浏览器的实现其执行效率更好。

而MVVM一类的框架比如React/Vue/Angular的流行，其双向绑定的特性已经让DOM的更新变成由框架自行处理，让前端工程师可以不需要操作DOM（改为让框架自行去操作[Virtual DOM](broken://pages/-M3x3ZVwyKaA-_4ttyP9)），只需要专注数据和业务逻辑。而且React/Vue/Angular这些主流框架针对DOM的操作时做了大量的[Repaint和Reflow](/frontend-hard-mode-interview/id-1/4.-liu-lan-qi-v8-yin-qing/1.4.2.md)有关的优化，比如基于Virtual DOM进行计算，将多次对真实DOM的操作精简为最小变动然后操作真实DOM、在同一个Event Loop循环内将多次DOM操作事件合并……这些优化措施都能有能更好的表现，而这些优化jQuery并没有做。

### 3. 动画领域的替代方案

现在CSS3动画技术已经非常的成熟，已经完全可以取代jQuery做的动画。css3能比jQuery的animate方法实现更复杂的动画，兼容性好，性能消耗小。举个例子，比方说如果实现背景颜色过度，CSS3可以完美的实现，但是jQuery就不方便。现在已经出现了很多优秀的css3动画库，比如Animate.css、Velocity.js。

### 4. Ajax也有了更好的替代

Fetch已经完美地取代Ajax成为实现异步任务的标准。jQuery的ajax操作，为我们省去了兼容浏览器方面的问题，并且也提供了简明的API去调用get和post，让开发者从繁琐的兼容性与使用原生API上解脱出来。但是现在，这个优势也已经非常微小了。不管是原生JavaScript的Fetch API还是第三方库axios，都为我们提供了强大的ajax使用能力，并且axios还有拦截器这个优势。这时相较而言，jQuery的ajax确实已经无法相比了。

当然，Fetch在IE浏览器里需要有Fetch的Polyfill方案：[github/fetch](https://link.zhihu.com/?target=https%3A//github.com/github/fetch)，这样只需要引用这一个小小的JS，就可以使用方便的ajax了，相较于jQuery小巧很多。

## 叁.1.1.3 jQuery留给我们的财富

### 1. 大量功能强大方便使用的插件

jQuery发展这么多年，它最大的价值之一在于社区积攒的各种插件。无论是做日期选择器还是轮播图，甚至搞个播放器，都可以分分钟找到一个对应的插件。 比如 [CSS transitions and transformations for jQuery](http://ricostacruz.com/jquery.transit/) 这个动画插件，我到现在也还在用，完全没问题。

更多宝矿可以自行浏览jQuery插件网站：<https://plugins.jquery.com/> 这个网站虽然不再接纳新的插件，但可以作为一份地图，可以方便找到jQuery流行插件的Github主页，然后你会发现，很多插件都还非常活跃而且更新非常频繁。

![plugins.jquery.com](https://1680353414-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnlixiOMXyluGpXDGGs%2F-M8Tei9aTGfFgA59xx3l%2F-M8Thmd3ibEyxBJwZFz-%2F3.1.1.3.1.jpg?alt=media\&token=91bf303e-4fb8-4f05-a384-d745f8769b00)

### 2.简洁易懂的API设计

jQuery 的 API 风格依然在流行。我们把 jQuery 和 [Axios ](https://github.com/axios/axios)做一下对比：

```javascript
$.ajax({url:'/api', method:'get'})
$.get('/api').then(fn1,fn2)

axios({ url: '/api', method: 'get'})
axios.get('/api').then(fn1, fn2)
```

为什么 2018 年开始流行的 axios 跟 jQuery.ajax 这么相像呢？因为 jQuery 的 API 实在太好用了！搞得新库根本没法超越它，没有办法设计出更简洁的 API 了。

### 3.一些鬼斧神工似的编程套路

为什么有些人代码水平老是提不高了？就是因为不会造轮子，不会设计优雅的 API，更不会实现优雅的 API，只会调用其他库或框架提供的功能（中枪的举手）。而 jQuery 则提供了简单而又经典的范例供大家学习。不信的话我们就来看看 jQuery 用到了哪些所谓的设计模式（其实就是编程套路）吧。

#### 函数重载

在[壹.2.1 函数](broken://pages/-LnmbB_Q43jxkznMaoOL) 里面最末尾有John Resig的一段有关“用原生JavaScript实现函数重载”的代码，已经见识到jQuery之父的coding能力。jQuery里的函数重载是这样的：

```javascript
$(fn)
$('div')
$(div)
$($(div))
$('span', '#scope1')
```

你会发现 $ 这个函数的参数可以是函数、字符串、元素和 jQuery 对象，甚至还能接受多个参数，这种重载是怎么做到的？读者可以自己去看看源码一探究竟。

#### 发布订阅者模式

```javascript
var eventHub = $({});
eventHub.on('xxx', function(){ console.log('收到') });
eventHub.trigger('xxx');
```

#### 用原型继承实现插件系统

```javascript
$.fn.modal = function(){ ... }
$('#div1').modal();
```

Vue 2 的插件也是类似的思路。

#### 事件委托

```javascript
$('div').on('click', 'span', function(){...});
```

说实话若在 2018 年找前端让他写一个事件委托，我保证 90% 写出来的代码都是有「明显」bug 的。

#### 链式调用

```javascript
$('div').text('hi').addClass('red').animate({left: 100});
```

#### 命名空间

```javascript
// 你的插件在一个 button 上绑定了很多事件
$button.on('click.plugin', function(){...})
$button.on('mouseenter.plugin', function(){...})
// 然后你想在某个时刻移除以上所有事件,如果不用 jQuery 就很麻烦
$button.off('.plugin');
```

#### 高阶函数

```javascript
var fn2 = $.proxy(fn1, asThis, param1)
```

$.proxy 接受一个函数，返回一个新的函数。

还有许多其他“套路”，限于篇幅就不一一列举了，读者可以自行探索。

## 结语

jQuery虽然完成了它的历史使命，并且在逐渐被新的库/框架所替代，但它给我们留下了很多宝贵的财富，仍然活跃在舞台上。

其实，阅读jQuery 的源码和学习它的编程思想，对写代码和封装库很有帮助。现在的前端工程师新人依然可以学习 jQuery 的思想，因为新人直接理解Vue/React/Angular的底层思想难度较大，而jQuery是一个很不错的中间过渡。

同时，jQuery 也蕴含了非常多的编程套路。如果你不想学jQuery，直接去学 React/Vue /Angular 会难一点，当然硬要学也能学会，但也仅此而已，反正回头还是要研究更深层次的JavaScript套路，这些在jQuery里都有。

最后，jQuery能支持IE8以下版本。由于Vue之类的框架只能支持IE8以上的版本，而实际情况是现在很多那种事业单位里的古董电脑很多都还是IE7，那么这种情况下，用vue之类的MVVM框架显然不适合。

如果你读到这里，想必也不会再问jQuery是否过时了。

## 参考文献

{% hint style="info" %}
<https://en.wikipedia.org/wiki/JQuery>\
<https://zh.wikipedia.org/wiki/%E6%B5%8F%E8%A7%88%E5%99%A8%E5%A4%A7%E6%88%98>
{% endhint %}
