JS高阶函数、闭包

高阶函数是什么?

高阶函数(higher-order-function)并不是JS中语言中所特有的东西,它适用于整个计算机领域,甚至数学领域。
高阶函数的定义比较简单:
A:接受一个或者多个函数作为输入
B:输出一个函数
在大部分计算机语言中,一个函数 的输入往往被看作是函数的参数,而一个函数的输出,往往被看作是函数的返回值。
JS中实现高阶函数
1.函数是一等公民
在JS语言中,函数被视为一等公民
什么是一等公民?就是函数可以像其他数据类型(数字、字符串、布尔等)一样,有权力出入任务场所,这一点在很多其他语言(比如Java、C#…)中是不太容易做到的。
函数可以保存到变量、作为参数传递、作为返回值返回
2.函数作为参数传递
用JS写一个函数定义,该函数要实现这样一个功能,将某件事重复做N次。
示例1function repeat(n, something) {    
     for (let i = 0; i < n; i++) {   
          something(); // 重复的调用something() 函数     
        } 
    }
    //上面的这个函数,就可以看作是一个高阶函数,因为,它的第二个参数需要接受一个函数,来表示到底要把什么事进行重复。
示例2function repeat(n, something) {    
for (let i = 0; i < n; i++) {         
      something();    
      } 
   }
  const func = function(){        
   console.log("hello"); }
   repeat(10, func); // 输出10个hello
   repeat(10, function(){    
     console.log("hello"); 
   }); //输出10个hello
   repeat(10, ()=>{ console.log("hello"); }); // 输出10个hello
//调用函数!只要保证第一个参数是一个数字,第二个参数是一个函数就可以。
3.函数作为返回值
示例3function test(){    
return function(a, b){         
      console.log(a + b);    
      } 
   }
  //该函数没有做任何事情,但它的运行后,会得到一个新的函数,这个新函数接受两个参数,并在控制台输出两个参数相加的结果。

什么是闭包?

闭包要满足两个条件:
A:一个函数中要嵌套一个内部函数,并且内部函数要访问外部函数的变量
B:内部函数要被外部引用
示例1function eat(){ 
   var food = '鸡肉';
    return function(){   
        console.log(food);    
        } 
    }
     var look = eat(); 
     look(); //  鸡肉
     look(); //  鸡肉
     // 这个示例,eat函数返回一个函数,并在这个内部函数中访问food这个局部变量,调用eat函数并将结果赋值给look变量,这个look指向了eat函数中的内部函数,然后调用它,最后输出food的值。
自由变量
闭包就是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。
什么是自由变量?
自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量
示例2function wrapper() {
    let freeVar = 42;
    function inner() {
        return 2 * freeVar;
    }
    return inner;
}
//自由变量在闭包生成之前,并不是函数的一部分。在函数被调用时,闭包才会形成,函数将这个自由变量纳入自己的作用域,也就是说,自由变量从此与定义它的容器无关,以函数被调用那一刻为时间点,成为函数中的成员。
闭包的作用域
虽然自由变量从闭包时起 “将和这个函数一同存在,即使已经离开了创造它的环境也不例外”,但我们必须搞清楚,闭包产生时的作用域。
示例3var scope = 'hello';
function echo(){
    console.log(scope);
}
function wrapper(){
    var scope = 'hello2';
    echo();
}
echo();    // 输出hello
wrapper(); // 输出hello
// 为什么在wrapper内部的echo()调用,会输出全局scope?因为:echo定义的位置,只能闭包到全局的scope,它的外层作用域就是全局
示例4//将代码变化一下
var scope = 'hello';
function echo(){
    console.log(scope);
}
function wrapper(){
    var scope = 'hello2';
    function echo(){
        console.log(scope);
    }
    echo();
}
echo();    //输出hello
wrapper(); //输出hello2
// 闭包的自由变量来自何处,和它的外层作用域(被定义的位置)也有关系
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包在编程中有很多应用场景,以下是一些常见的例子: 1. 数据封装和私有变量:闭包可以用来创建私有变量,从而实现数据封装和保护。这在模块化编程和面向对象编程中非常有用。 2. 函数工厂:闭包可以用来创建一系列相关的函数,这些函数共享相同的外部变量。这在创建类似于Python中的装饰器或JavaScript中的高阶函数时非常有用。 3. 延迟执行和计时器:闭包可以用来实现延迟执行和定时器功能。例如,在JavaScript中,setTimeout和setInterval函数使用闭包来实现延迟执行和定时器功能。 4. 记忆化(Memoization):闭包可以用来实现记忆化,即缓存函数的计算结果,以便在后续调用中重用。这可以提高函数的性能,特别是在处理计算密集型任务时。 5. 事件处理和回调函数:在JavaScript等事件驱动的编程环境中,闭包常用于实现事件处理和回调函数。闭包可以捕获事件处理函数的上下文,使得事件处理函数可以访问其所需的外部变量。 6. 部分应用(Partial Application)和柯里化(Currying):闭包可以用来实现部分应用和柯里化,这是一种将多参数函数转换为一系列单参数函数的技术。这可以简化函数调用,使得代码更加简洁和可读。 7. 实现迭代器和生成器:在某些编程语言中,例如Python和JavaScript,闭包可以用来实现迭代器和生成器,这是一种用于遍历数据结构的高效方法。
最新发布
07-14

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值