1、什么是闭包

是对js作用域特性的一种应用,因为函数内定义的局部变量不能被外部获取,而函数却可以访问到其外部作用域的变量,所以可以在其内部定义一个访问局部变量的方法,并将之输出到外部,return出去,也就是在函数销毁之后通过函数输出的方法来访问局部变量。

2、闭包的作用

先看几个栗子🌰

for (var i = 0; i < 5; ++i) {
  setTimeout(function() {
    console.log(i + " ");
  }, 100);
}

  输出结果为 5 5 5 5 5

原因: js 运行环境为单线程,setTimeout 注册的函数需要等到线程空闲时才能执行,此时 for 循环已经结束,i 值为 5,又因为循环中 setTimeout 接受的参数函数通过闭包访问变量 i,所以 5 个定时输出都是 5。

修改方法:将 setTimeout 放在立即执行函数中,将 i 值作为参数传递给包裹函数,创建新闭包。

for (var i = 0; i < 5; ++i) {
  (function(i) {
    setTimeout(function() {
      console.log(i + " ");
    }, 100);
  })(i);
}

  输出结果为: 0 1 2 3 4

function add() {
  var x = 1;
  console.log(++x);
}

add(); //执行输出2,

add(); //执行还是输出2,

  怎样才能使每次执行有加 1 效果呢?使用闭包

function add() {
  var x = 1;
  return function() {
    console.log(++x);
  };
}
var num = add();

num(); //输出2,

num(); //输出3,

num(); //输出4,

  1.模仿块级作用域

      2.储存变量

  3.封装私有变量

3.闭包的应用

防抖debounce

function debounce(fn,delay){
    let timer = null;
    return function(){
        let context = this
        let args = arguments
        clearTimeout(timer)
        timer = setTimeout(function(){
            fn.apply(context,args) 
        },delay)
    }
}
let flag = 0
function foo(){
    flag++
    console.log('Number of calls:%d',flag)
}

document.addEventListener('click',debounce(foo,1000))

节流 throttle

function throttle(fn,delay){
    let timer = null;
    let startTime = Date.now()

    return function(){
        let curTime = Date .now()
        let remaining = delay - (curTime -startTime)
        const context = this
        const args = arguments

        clearTimeout(timer)
        if(remaining<=0){
            fn.apply(context,args)
            startTime = Date.now();
        }else{
            timer = setTimeout(fn,remaining)
        }
    }
}
function xxx(){
    console.log('1')
}
document.addEventListener('click', throttle(xxx,5000))

  

setTimeout

function f1(a) {
    function f2() {
        console.log(a);
    }
    return f2;
}
var fun = f1(1);
setTimeout(fun,1000);//一秒之后打印出1

 封装私有变量

function f1() {
    var sum = 0;
    var obj = {
       inc:function () {
           sum++;
           return sum;
       }
};
    return obj;
}
let result = f1();
console.log(result.inc());//1
console.log(result.inc());//2
console.log(result.inc());//3

  对于防抖和节流的理解参考:https://www.jianshu.com/p/c8b86b09daf0

posted on 2020-04-15 17:38  白不了的黑发  阅读(135)  评论(0编辑  收藏  举报