zoukankan      html  css  js  c++  java
  • 作用域、闭包及其应用

    闭包是有权访问另一个作用域中的变量的函数。

    如果你找部门A办事,部门A说你得先去B部门盖章,部门B又说你得去部门C盖个章……这叫踢皮球。而闭包与之相反,它是负责到底,部门A的人会自动去和其他部门进行协调。

    在JS中,闭包与作用域是分不开的,只要理解了作用域即可理解闭包。

    一个简单闭包

    在某些情况下,我们可能需要访问另一个作用域中的变量,使用函数即可创建一个作用域:

    function Life(){
      let count = 0;
      return function(num){
        console.log(`Before add: ${count}`);
        count += num;
        console.log(`After add: ${count}`);
      }
    }
    
    let lifeAdd = Life();
    lifeAdd(2);	//Before add: 0   After add: 2
    

    这里return出来的函数其实就是闭包给外界的一个接口,如果不这样,给外层作用域中的对象设置一个方法也可以,比如window:

    function Life(){
      let count = 0;
      window.lifeAdd = function(num){
        console.log(`Before add: ${count}`);
        count += num;
        console.log(`After add: ${count}`);
      }
    }
    Life();
    lifeAdd(2);	//Before add: 0   After add: 2
    

    虽然Life函数已经执行完毕,但由于闭包的存在,Life函数的内部变量一直没有被销毁。

    闭包:函数防抖(debounce)与函数节流(throttle)

    在实际应用中,控制一段代码的执行时机是很常见的。

    有两个很常见的场景类型:

    防抖(debounce)

    在高频率触发的事件中,两次触发的时间间隔超过一定限度时才执行处理函数,否则重新计时。

    就像电梯一样,每进去一个人,电梯就重新计时,几秒钟之后再无人进入时才会关门。

    function debounce(fn, interval = 300) {
        let timeout = null;
        return function () {
            clearTimeout(timeout);
            timeout = setTimeout(fn, interval);
        };
    }
    //每次触发事件时,都会设置新的定时器,清除已有定时器
    //而如果事件触发间隔超过了300毫秒,已有的定时器就会执行它的回调函数
    window.onmousemove = debounce(function(){console.log('---')}, 300)
    

    上面的debounce函数没有向回调函数传递参数,下面是带参数版:

    function debounce(fn, interval = 300) {
        let timeout = null;
        return function () {
            clearTimeout(timeout);
            timeout = setTimeout(
              ()=fn((new Date()).toLocaleString()),	
              interval
            );
        };
    }
    //假设回调函数每次执行都需要打印一个字符串
    window.onmousemove = debounce(function (str){
        console.log(str)
    }, 300)
    

    节流

    在高频率触发的事件中,不论触发频率变得多高,都是每隔一段时间执行一次处理函数。

    const throttle = (func, wait) = {
      let timer = null;
      return () = {
        if (timer) {
          return;
        }
    
        timer = setTimeout(() = {
          func((new Date()).toLocaleString());
          timer = null;
        }, wait);
      };
    };
    window.onmousemove = throttle(function (time){
        console.log(time)
    }, 1000)
    

    防抖与节流的最大区别就是,防抖是只有在事件触发慢下来的时候才执行,而节流是以恒定的频率执行。

  • 相关阅读:
    linux全方位掌握一个命令--思路比方法更重要
    grep命令详解
    linux中的通配符与正则表达式
    sed命令使用详解归纳
    linux下命令行操作快捷键及技巧
    (原创)发布一个C++版本的ORM库SmartDB(一)
    (原创)C++11改进我们的程序之简化我们的程序(八)
    (原创)C++11改进我们的程序之简化我们的程序(七)
    (原创)C++11改进我们的程序之简化我们的程序(六)
    (原创)C++11改进我们的程序之简化我们的程序(五)
  • 原文地址:https://www.cnblogs.com/MPK-dev/p/12900291.html
Copyright © 2011-2022 走看看