JS中的五个高阶函数|青训营笔记

183 阅读4分钟

JS中的五个高阶函数|青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第5天。 今天对昨天的JS进阶内容做了实践,将经验收获分享给大家!

一、本节课重点内容:

    本节课将介绍常用的五大高阶函数: 防抖(debounce)、节流(throttle)、回调、预置、偏函数。

二、课堂知识点纪要:

  • 高阶函数定义

       高阶函数就是一个将函数作为参数或者返回值的函数
    
       function add(x,y,fn){
          return fn(x) + fn(y);
       }
       //当我们调用add(-5,6,Math.abs)时,我们不难发现,函数的执行过程为
       x = -5;
       y = 6;
       f = Math.abs;
       f(x) + f(y) ==> Math.abs(-5) + Math.abs(6) ==> 11;
      
    
  • 柯里化

      柯里化函数首先会接收一些参数,接收后,继续返回另一个函数,传入的参数在函数形成的闭包中被保存。待到函数被真正需要时,所有保存的参数都会被一次性用于求值。
      
       function curry(company, department) { //接收固定的公司、部门
         return function (name, age) {
           console.log(`我是 ${company} ${department} 部门的 ${name}${age} 岁`);
         }
       }
       let print = curry('ali', 'F77'); // 传递固定的公司、部门
    
       print('zhangsan', 20);//调用 return 出来的函数并传变化的参数
       print('lisi', 30);
    
  • 五个高阶函数:

    • 回调函数

      回调是一种将函数坐会返回值执行的高阶函数,借助回调可以实现递归。

          // 作为返回值输出
             function fn(){
                 return function(){}
             }
             fn()
        
      
    • 偏函数

      偏函数是将一个“纯函数的返回值”作为独立变量,可以理解为初始化默认值,方便在新函数中调用、返回。

         function isType(type) {
             return function(obj) {
                 return Object.prototype.toString.call(obj) === `[object ${type}]`
             }
         }
      
         const isArray = isType('Array');
         const isString = isType('String');
         console.log(isArray([1, 2, [3,4]])); // true
         console.log(isString({}));           // false
      
    • 预置函数

      预置函数即预先设置了返回条件的高阶函数。

       function after(time, cb) {
         return function() {
             if (--time === 0) {
                 cb();
             }
         }
         }
          //预置条件:吃三碗才能吃饱
         let eat = after(3, function() {
             console.log('吃饱了');
         }); 
         eat();
         eat();
         eat();
         // eat函数(条件)只有执行3次的时候才会输出'吃饱了'
        
      
    • 防抖函数

         const debounce = (func, wait) => {
           //定义一个计时器
           let timer;
           return () => {
             clearTimeout(timer);
             timer = setTimeout(func, wait);
           };
         };
      
      
         function debounce(fn, delay) {
             // timer 是在闭包中的
             let timer = null;
             let that = this;
             let _args = arguments;
             return function() {
                 if (timer) {
                     clearTimeout(timer)
                 }
                 timer = setTimeout(() => {
                     fn.apply(that, _args)
                     timer = null
                 }, delay)
             }
         }
      
    • 节流函数

       const throttle = function(fn, interval){
             let that = fn, //保存需要被延迟执行的函数引用
             timer, //定时器
             firstTime = true;//是否为第一次调用
             return function(){
                 let args = arguments;
                 _this = this;
                 if(firstTime){
                     that.apply(_this, args);
                     return firstTime = false;
                 }
                 if(timer){//如果定时器还在,则说明前一次延迟执行还没有完成
                     return false;
                 }
                 timer = setTimeout(function(){
                     clearTimeout(timer);
                     timer = null;
                     that.apply(_this, args);
                 },interval || 1000)
             }
         }
      

三、实践练习案例:

  • Styled-Compnent样式:

             //Authored by iiru
             //powerby styled.js
             import styled from "styled-components";
             export const MainContain =styled.div`
            width:100%;
            height:1000px;
            background-image: linear-gradient(to right, #f49ecb,#d94bcc);
    
           .mainContent{
            margin:5% 25% 0 25%;
            width:500px;
            height:16%;
            background:#391a33;
           }
         `
         export const MainContent =styled.div`
              margin:4% 45%;
              width:200px;
              float:right;
              font-size:32px;
              color:#efefef;
    
  • TS 防抖代码:

//Authored by iiru
//powerby styled.js
import React from "react";
import { MainContain,MainContent} from "./bounce";
import { Input,Button,InputRef,message} from 'antd';

//输入框接口
interface Login {
   account: string|InputRef|null;
   password: string|InputRef| null;
}
//防抖函数
const debounce=(func:any, delay:number)=>{
   let timer: NodeJS.Timeout | null;
   return ()=>{
       let context = this;
       if(timer) clearTimeout(timer);
       timer = setTimeout(  function(){
           func.apply(context,arguments);
       },delay)
   }
}

//页面组件通过Button和Input调用防抖函数
export function Debounce(){
    const loginData:Login = {
       account: ' ',
       password:' '
   }
   const tips=(e:any)=>{
        console.log(e)
       if(e.account.input.value && e.password.input.value ) message.success("Hello!"+e.account.input.value)
       else if(!e.account.input.value) message.error("No focus account!")
       else if(!e.password.input.value) message.error("No focus password!")
}

   const submit:() => void =debounce(()=>tips(loginData),3000)
   return (
         <>
            <MainContain>
                <MainContent
                >
                       <Input className={"Inputy"} placeholder="input account"  ref={input => loginData.account = input} />
                       <Input.Password className={"Inputy"} placeholder="input password"  ref={input => loginData.password = input} />
                       <Button onClick={submit}>登录</Button>
                </MainContent>
            </MainContain>
         </>
   )
};

四、参考文献:

五、心得体会:

    今天学习了高阶函数的运用,高阶函数在处理函数返回逻辑非常实用。当应用场景出现网络请求时,高阶函数
    可以很优雅的校验请求,减轻服务器载荷。不过这只是高阶函数的运用的冰山一角,仍需通过项目大量垂帘
    形成适合自己的函数风格,比如我在尝试用ts封装防抖时出现了各种问题,只有在实践中才能发现,发现问题
    解决问题,才能够提升!