Bootstrap

angularjs 截流_完全搞懂JavaScript的闭包、防抖跟节流

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

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

90a4d9e3d23a7dd10ffcbf3d03a85e57.png

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

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

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

闲话少说,开始正文。安全

1、谈谈对闭包的理解

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

直观点来说,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 跟上面是有区别的,上面是用了个变量将其保存了起来。

闭包的优缺点以下:

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

二、能够把这个变量看成缓存来使用

弊端:没法销毁变量,使用不当,容易形成内存泄漏闭包

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

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

2、谈谈对防抖的理解

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

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

56cf748c9fe206c1c14f728d2abd54aa.png

试想,若是是咱们,怎么去实现这个功能,正常状况下,咱们确定会这样写函数

//相应的js代码

var txt_test=document.getElementById("txt_test");

txt_test.οninput=function(){

console.log(txt_test.value);

//其余代码

请求后端数据

}

对应的结果

6931fa98f8fec1189d41dfd67caa9c26.png

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

联想到实际

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

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

当咱们搜索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方法。

3、谈谈对节流的理解

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

试想,若是是咱们,须要实现以上的功能,咱们是如何写代码的。

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

window.οnscrοll=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方法。

总结

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

3a70565aac34456a89147d7a.html

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

使用的都是计时器setTimeout,

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

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

e9016e102385af823660177a6f37acba.png

;