天天看点

彻底搞懂JavaScript的闭包、防抖跟节流

最近出去面试了一下,收获颇多!!!

以前的我,追求实际,比较追求实用价值,然而最近面试,传说中的面试造火箭,工作拧螺丝,竟然被我遇到了。虽然很多知识点在实际工作中并不经常用到,但人家就是靠这个来筛选人才的!!!

彻底搞懂JavaScript的闭包、防抖跟节流

在大学里,你可能会感觉到微积分没啥用处,去菜市场买菜,你不可能用到微积分吧,但是呢,这个知识却决定了你能在哪个菜市场买菜。请细品!

关于前端方面,我用的是jQuery,前端采用Ajax请求数据,后端返回JSON数据,得到数据后,再通过jQuery去操作DOM。

这里可能有个误解,很多人会以为jQuery是一种框架,然而现实并非如此,它只是个工具库而已,简化了JavaScript的一些语法。可能很多人用习惯了jQuery后,甚至都分不清jQuery语法跟JavaScript语法。jQuery能做的事情,JavaScript也能做,只是简单地简化了一些写法。

闲话少说,开始正文。

从概念上来讲,所谓的闭包指的是一个函数,一个什么样的函数呢?有权访问另一个函数作用域中的变量的函数。

直观点来讲,JavaScript的闭包就是函数中嵌套函数。

本质上来讲,是因为作用域而产生一种特殊的情况,从而导致函数内部的变量无法进行销毁。如果再去深究的话,会出现个作用域链,这里面比较难理解。也是闭包产生的根本原因。

举个例子:

闭包的优缺点如下:

优点:1、保护函数内部的变量安全,实现封装

2、可以把这个变量当作缓存来使用

弊端:无法销毁变量,使用不当,容易造成内存泄漏

你可能会问,闭包的使用场景到底是什么呢?

这个问题可能令你很是疑惑,我也想了很久。直到最近的一次面试,才豁然开朗。接下来看看js的防抖跟节流。

防抖,从字面上来理解,便是防止抖动。

这个,我们应该会经常接触到,可能自己不知道而已。我们经常使用百度吧,没事百度搜索一下。在这里,当我们输入关键词的时候,会出现一些联想词,供我们去选择。这里面便用到了防抖。

彻底搞懂JavaScript的闭包、防抖跟节流

试想,如果是我们,怎么去实现这个功能,正常情况下,我们肯定会这样写

对应的结果

彻底搞懂JavaScript的闭包、防抖跟节流

这样写,的确不错。每输入一个字符,触发一次输入事件。

联想到实际

现实中使用百度的人成千上万,那每次输入一个字符,请求后端一次,这么多人的话同时使用百度的话,那请求也太多了,肯定会导致服务器压力贼大,我们知道,这些请求中很多是没有什么实际意义的,基于这种场景,怎么优化呢?

试想一下,现实中,我们是怎么搜索的?

当我们搜索ghost的时候,应该是快速地输入,不可能一个字符一个字符的输入的吧,那打字速度也忒慢了吧。当输入完的时候,肯定会停顿一下,而这时候再去触发一次输入事件岂不正好?此时,防抖,应运而生。

以上的代码便是百度搜索中,不管怎么输入,只有在输入完成后,停顿5s(这个时间故意设置这么长的),才会触发一次handle方法。

我们应该也会经常接触到,比如打开一个网页,往下滚动的时候,会出现滚动条,当滚动到一定的程度时,会出现一个返回顶部的按钮,点击一下,便会返回到顶部。在这里,便会用到节流。

试想,如果是我们,需要实现以上的功能,我们是如何写代码的。

首先,先写一个div通过position:fixed;display:none;固定到页面右下角。然后写一个滚动事件,

在这里,当我们向下滚动页面的时候,你会发现,这个onscroll事件触发的频率太高太高,稍微向下滚动一丢丢,就已经触发了很多次,而且其中很多的触发并没有实在的意义,如何减少触发的频率,减少那么多的计算操作呢?

现实中,屏幕刷新率一般在60HZ,我们看到的静态画面并不是完全不动的,只是动的太快,人眼无法觉察出,误以为是不动的。如果过慢的话,我们自然会看得出来,过快的话,没啥实际意义,刷新的过快了,通过人眼,我们还是认为屏幕是不动的。

既然这样,那可不可以这样?

在人眼识别的范围内,间接地去触发这个事件。岂不正好?这时候,节流便诞生了。

所谓的节流呢,其思想指的就是某些代码不可以在没有间断的情况下连续重复执行。类似的还有onresize等事件。

以上的代码便是触发窗口滚动事件后,每2s执行一次handle方法。

以上的防抖跟节流的方法,都是比较基础的方法。至于怎么升级,就靠个人了

彻底搞懂JavaScript的闭包、防抖跟节流

防抖跟节流都用到了闭包,

使用的都是计时器setTimeout,

防抖是某个事件触发后几秒后执行相应的方法,

而节流是某个事件触发后周期性执行相应的方法。

彻底搞懂JavaScript的闭包、防抖跟节流