彻底搞懂JavaScript的闭包、防抖跟节流
最近出去面试了一下,收获颇多!!!
以前的我,追求实际,比较追求实用价值,然而最近面试,传说中的面试造火箭,工作拧螺丝,竟然被我遇到了。虽然很多知识点在实际工作中并不经常用到,但人家就是靠这个来筛选人才的!!!

在大学里,你可能会感觉到微积分没啥用处,去菜市场买菜,你不可能用到微积分吧,但是呢,这个知识却决定了你能在哪个菜市场买菜。请细品!
关于前端方面,我用的是jQuery,前端采用Ajax请求数据,后端返回JSON数据,得到数据后,再通过jQuery去操作DOM。
这里可能有个误解,很多人会以为jQuery是一种框架,然而现实并非如此,它只是个工具库而已,简化了JavaScript的一些语法。可能很多人用习惯了jQuery后,甚至都分不清jQuery语法跟JavaScript语法。jQuery能做的事情,JavaScript也能做,只是简单地简化了一些写法。
闲话少说,开始正文。
一、谈谈对闭包的理解
从概念上来讲,所谓的闭包指的是一个函数,一个什么样的函数呢?有权访问另一个函数作用域中的变量的函数。
直观点来讲,JavaScript的闭包就是函数中嵌套函数。
本质上来讲,是因为作用域而产生一种特殊的情况,从而导致函数内部的变量无法进行销毁。如果再去深究的话,会出现个作用域链,这里面比较难理解。也是闭包产生的根本原因。
举个例子:
function myMethod(){
var num=6;
return function(){
var n=0;
console.log(++n);
console.log(++num);
}
}
myMethod();//执行后,返回的是个方法(就是所谓的闭包),因为这个方法中还用到了myMethod里面的变量num,会导致num无法释放。
//可以证明
var myFn=myMethod();//将返回的方法用变量保存起来
myFn();//此时的n=1,num=7 num没有被销毁,仍然保存着值。这便是闭包的精髓所在,有点像C#/JAVA里面的静态变量
myFn();//此时的n=1,num=8
myMethod()();//如果这样运行的话,输出永远是n=1,num=7 跟上面是有区别的,上面是用了个变量将其保存了起来。
闭包的优缺点如下:
优点:1、保护函数内部的变量安全,实现封装
2、可以把这个变量当作缓存来使用
弊端:无法销毁变量,使用不当,容易造成内存泄漏
你可能会问,闭包的使用场景到底是什么呢?
这个问题可能令你很是疑惑,我也想了很久。直到最近的一次面试,才豁然开朗。接下来看看js的防抖跟节流。
二、谈谈对防抖的理解
防抖,从字面上来理解,便是防止抖动。
这个,我们应该会经常接触到,可能自己不知道而已。我们经常使用百度吧,没事百度搜索一下。在这里,当我们输入关键词的时候,会出现一些联想词,供我们去选择。这里面便用到了防抖。

试想,如果是我们,怎么去实现这个功能,正常情况下,我们肯定会这样写
<input type="text" id="txt_test" />
//相应的js代码
var txt_test=document.getElementById("txt_test");
txt_test.oninput=function(){
console.log(txt_test.value);
//其他代码
请求后端数据
}
对应的结果

这样写,的确不错。每输入一个字符,触发一次输入事件。
联想到实际
现实中使用百度的人成千上万,那每次输入一个字符,请求后端一次,这么多人的话同时使用百度的话,那请求也太多了,肯定会导致服务器压力贼大,我们知道,这些请求中很多是没有什么实际意义的,基于这种场景,怎么优化呢?
试想一下,现实中,我们是怎么搜索的?
当我们搜索ghost的时候,应该是快速地输入,不可能一个字符一个字符的输入的吧,那打字速度也忒慢了吧。当输入完的时候,肯定会停顿一下,而这时候再去触发一次输入事件岂不正好?此时,防抖,应运而生。
function debounce(fn,wait) {
var timeout = null; // 创建一个标记用来存放定时器的返回值
return function () {
clearTimeout(timeout); //清除定时器
//创建新的 setTimeout
timeout = setTimeout(function(){
fn();
}, wait);
};
}
// 处理函数
function handle() {
console.log(document.getElementById("kw").value);
}
//输入框事件
document.getElementById("kw").addEventListener('input', debounce(handle,5000));
以上的代码便是百度搜索中,不管怎么输入,只有在输入完成后,停顿5s(这个时间故意设置这么长的),才会触发一次handle方法。
三、谈谈对节流的理解
我们应该也会经常接触到,比如打开一个网页,往下滚动的时候,会出现滚动条,当滚动到一定的程度时,会出现一个返回顶部的按钮,点击一下,便会返回到顶部。在这里,便会用到节流。
试想,如果是我们,需要实现以上的功能,我们是如何写代码的。
首先,先写一个div通过position:fixed;display:none;固定到页面右下角。然后写一个滚动事件,
window.onscroll=function(e){
//相应的处理代码
handler();距离多少的位置,显示按钮或者隐藏按钮。
}
function handler(){
console.log("滚动事件触发");
}
在这里,当我们向下滚动页面的时候,你会发现,这个onscroll事件触发的频率太高太高,稍微向下滚动一丢丢,就已经触发了很多次,而且其中很多的触发并没有实在的意义,如何减少触发的频率,减少那么多的计算操作呢?
现实中,屏幕刷新率一般在60HZ,我们看到的静态画面并不是完全不动的,只是动的太快,人眼无法觉察出,误以为是不动的。如果过慢的话,我们自然会看得出来,过快的话,没啥实际意义,刷新的过快了,通过人眼,我们还是认为屏幕是不动的。
既然这样,那可不可以这样?
在人眼识别的范围内,间接地去触发这个事件。岂不正好?这时候,节流便诞生了。
所谓的节流呢,其思想指的就是某些代码不可以在没有间断的情况下连续重复执行。类似的还有onresize等事件。
function throttle(fn,delay){
var canRun=true;//通过闭包保存该变量
return function(){
if(!canRun) return;//立刻返回
canRun=false;
setTimeout(function(){
fn();
canRun=true;
},delay);
};
}
function handle(){
console.log(123);
}
window.addEventListener("scroll",throttle(handle,2000));
以上的代码便是触发窗口滚动事件后,每2s执行一次handle方法。
总结
以上的防抖跟节流的方法,都是比较基础的方法。至于怎么升级,就靠个人了
。
防抖跟节流都用到了闭包,
使用的都是计时器setTimeout,
防抖是某个事件触发后几秒后执行相应的方法,
而节流是某个事件触发后周期性执行相应的方法。

彻底搞懂JavaScript的闭包、防抖跟节流的更多相关文章
- 来一轮带注释的demo,彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
- 一张图彻底搞懂JavaScript的==运算
一张图彻底搞懂JavaScript的==运算 来源 https://zhuanlan.zhihu.com/p/21650547 PS:最后,把图改了一下,仅供娱乐 : ) 大家知道,==是JavaSc ...
- 来聊聊JavaScript中的防抖和节流
目录 JavaScript防抖和节流 问题还原 防抖 什么是防抖 使用场景 节流 什么是节流 使用场景 JavaScript防抖和节流 问题还原 我们先来通过代码把常见的问题还原: <html& ...
- 彻底搞懂Javascript的“==”
本文转载自:@manxisuo的<通过一张简单的图,让你彻底地.永久地搞懂JS的==运算>. 大家知道,==是JavaScript中比较复杂的一个运算符.它的运算规则奇怪,容让人犯错,从而 ...
- 彻底搞懂JavaScript中的继承
你应该知道,JavaScript是一门基于原型链的语言,而我们今天的主题 -- "继承"就和"原型链"这一概念息息相关.甚至可以说,所谓的"原型链&q ...
- 一张图带你搞懂Javascript原型链关系
在某天,我听了一个老师的公开课,一张图搞懂了原型链. 老师花两天时间理解.整理的,他讲了两个小时我们当时就听懂了. 今天我把他整理出来,分享给大家.也让我自己巩固加深一下. 就是这张图: 为了更好的图 ...
- JavaScript 中的防抖和节流
什么是防抖 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时.如下图,持续触发 scrol ...
- JavaScript中函数防抖、节流
码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...
- 一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结
1. JavaScript内置对象 所谓的内置对象 指的是:JavaScript本身就自己有的对象 可以直接拿来就用.例如Array String 等等.JavaScript一共有12内置对象 ...
随机推荐
- 2016 piapiapia 数组绕过
0x00.感悟 写完这道题,我感觉到了扫源码的重要性.暑假复现的那些CVE,有的就是任意文件读取,有的是任意命令执行,这些应该都是通过代码审计,得到的漏洞.也就和我们的CTF差不多了. ...
- Go-数据类型-字符串-string
字符串 -- string 字符串使用双引号表示 " " 多行或原始字符串(反斜杠失去转义行为)使用 反引号 `` 字符使用单引号表示 ' ',表示单独的字母.中文.数字 字符串转 ...
- Scrum 冲刺第四天
一.每日站立式会议 1.会议内容 1)进行每日工作汇报 张博愉: 昨天已完成的工作:搜寻测试相关的资料 今日工作计划:编写测试计划 工作中遇到的困难:对测试接触得较少,有点头疼 张润柏: 昨天已完成的 ...
- 总括订单Blanket order
总括订单Blanket order是客户向其供应方发出的采购订单,但其中包含一段时间内的多个交货日期,通常使用谈判时的预定价格.大多数情况下,它用于对消耗性商品有经常性需求的情况.总括订单通常用于客户 ...
- Codeforces Edu Round 64 A-D
A. Inscribed Figures 分类讨论打表即可. PS:这道题翻译有歧义. 这样稍微翻转一下,就可以是\(7\)个交点呀...(大概是我没看英文题干导致的惨案) #include < ...
- 二、java多线程编程核心技术之(笔记)——如何停止线程?
1.异常法 public class MyThread extends Thread { @Override public void run() { super.run(); try { for (i ...
- 5+App 相关记录
一.页面跳转到app 1.应用的manifest.json文件,plus --> distribute --> google 节点下,增加属性 schemes 2.打包后,在手机里安装. ...
- 微信小程序日期转换、比较、加减
直接上干货: 在utils目录下新建一个dateUtil.js,代码如下:(在需要用的地方引入这个js,调用相关方法传入对应参数就可以使用了) 该工具脚本,实用性很高,通用于各类前端项目,熟悉后亦可以 ...
- java中什么是对象,什么是对象引用
在Java语句中,我们都会用到"=",但是这个"="的意义大部分人都没有一个清楚明确的认知 例如:Student a = new Student(); Stud ...
- DRF比Django的认证和权限高在哪里
Django可以用LoginRequiredMixin和PermissionRequiredMixin给类视图添加认证和权限,DRF做了高级封装,提供了更简洁的实现方式.我们通过继续学习官网教程来进行 ...