高阶函数总结

一、函数成员
函数中有一个name属性------>函数的名字,属性只读,不能修改
函数中有一个length属性----->函数定义的时候形参的个数

<script>
function f1(a,b,c){
    console.log(f1.name);
    console.log(f1.length);
}
f1();//f1 3
</script>

函数中有一个argumnet属性---->函数实参的个数----返回的是一个对象

<script>
function f2(a,b,c,d,e){
    console.log(f2.length);//5
    console.log(f2.arguments);//Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    console.log(f2.arguments.length);//5
}
f2(1,2,3,4,5);//
</script>

函数中有一个caller属性---->调用者(f3函数在f4函数中调用的,此时调用者是f4)

<script>
function f3(){
    console.log(f3.caller);
}
function f4(){
    f3();
}
f4();
</script>

二、函数作为参数
参数可以是匿名函数
参数也可以是命名函数:只传入命名函数额名字,并且是没有括号的(代表的是函数的代码内容),有括号的是调用

<script>
function f1(fn){
    console.log("f1的函数");
    fn();//此时fn当成一个函数来使用的
}
//fn是参数,最后作为函数来使用了,函数是可以作为参数来使用的
//调用f1,参数传入匿名函数
f1(function(){
    console.log("我是匿名函数");
});//f1的函数  我是匿名函数

//调用f1,参数传入命名函数;
f1(f2);//f1的函数 我是命名函数
function f2(){
    console.log("我是命名函数");
}
</script>

定时器里传入函数作为参数

<script>
    function f1(fn){
        setInterval(function(){
            console.log("定时器开始");
            fn();
            console.log("定时器结束");
        },1000);
    }
    //调用函数,传入匿名函数
    f1(function(){
        console.log("我是传入的函数作为参数");
    });//定时器开始   我是传入的函数作为参数 定时器结束----循环
</script>

三、函数作为返回值
return的含义

<script>
    function f1(){
       console.log("nice");
        return console.log("perfect");
    }
    //函数的调用是执行函数的过程
    f1();//nice perfect
    //有return的函数,return后面的内容是返回的内容,需要定义一个新变量去接收,然后再对新变量进行操作
    var ff=f1();
    //举个例子:
    //函数,目的就是利用它完成某一件事,事情完成了就有一个结果。把一个方法比喻成一台//石磨,黄豆和水相当于参数,经过石磨加工得到的豆浆就相当于返回值。
</script>

判断这个对象和传入的类型是不是同一个类型

<script>
function getFunc(type){
    return function(obj){
        return Object.prototype.toString.call(obj)===type;
    }
}
//传入的是数组
var ff=getFunc("[object Array]");
var result=ff([10,20,30]);
console.log(result);//true
//传入的是日期对象
var ff1=getFunc("[object Object]");
var dt=new Date();
var result1=ff1(dt);
console.log(result1);//false
</script>

sort() 方法对数组的元素进行排序,并返回数组。 sort 排序不一定是稳定的。默认排序顺序是根据字符串Unicode码点。
解决办法:添加一个匿名函数作为sort方法的参数使用,此时匿名函数中有两个参数

<script>
//例1:对数字进行排序,从小到大
var arr1=[1,100,20,40,10,200,5];
arr1.sort(function(obj1,obj2){
    if(obj1>obj2){
        return 1;
    }else if(obj1==obj2){
        return 0;
    }else{
        return -1;
    }
});
console.log(arr1);//[1, 5, 10, 20, 40, 100, 200]
//例2:对字符串进行排序
var arr2=["fashion","perfect","good","great","handsome","nice"]
arr2.sort(function(obj1,obj2){
    if(obj1>obj2){
        return 1;
    }else if(obj1==obj2){
        return 0;
    }else{
        return -1;
    }
});
console.log(arr2);//["fashion", "good", "great", "handsome", "nice", "perfect"]
</script>

扩展案例:排序,三部电影,电影有名字,大小,上映时间,都可以按照某个属性进行排序

<script>
    function File(name,size,time){
        this.name=name;//电影名
        this.size=size;//文件大小
        this.time=time;//电影上映时间
    }
    var f1=new File("eric.avi","400M","2004-5-23");
    var f2=new File("jack.avi","900M","2017-5-23");
    var f3=new File("rose.avi","200M","2010-5-23");
    var arr=[f1,f2,f3];
    function fn(attr){
        //函数作为返回值
        return function getSort(obj1,obj2){
            if(obj1[attr]>obj2[attr]){
                return 1;
            }else if(obj1[attr]==obj2[attr]){
                return 0;
            }else{
                return -1;
            }
        }
    }
    var ff=fn("name");//此处可以换成size或者time
    arr.sort(ff);
    for(var i=0;i<arr.length;i++){
        console.log(arr[i].name+"======="+arr[i].size+"======"+arr[i].time);
    }
</script>

四、函数变量、作业域、预解析
变量:局部变量(函数中用var定义的变量)和全局变量以及隐式全局变量
作用域:局部作用域和全局作用域
js中没有块级作用域----一对括号中定义的作用域,可以在括号外面使用
作用域链:变量的使用,从里到外,层层搜索,搜索到了直接使用,如果到0级作用域依然没有找到这个变量,则报错

<script>
var num=10;//作用域 级别:0
function f1(){
    var num=20;//作用域 级别:1
    function f2(){
        var num=30;//作用域 级别:2
        console.log(num);
    }
    f2();
}
f1();//30

预解析:浏览器解析代码之前做的事,把变量的声明和函数的声明提前(提升)到该作用域的最上面

<think>好的,我现在要回答关于JavaScript高阶函数的问题。首先,我需要确保自己正确理解高阶函数的概念。高阶函数是指那些可以接收其他函数作为参数,或者返回一个函数作为结果的函数。对吗?嗯,对的,这应该是基本定义。 接下来,我得想想如何组织回答的结构。用户希望结构清晰,逐步解释,所以可能需要分点说明,比如先定义,再举例,再讲常见的高阶函数,比如map、filter、reduce这些数组方法。然后或许可以提到函数作为返回值的例子,比如闭包或者函数工厂。 不过,要注意用户提到的系统级指令,比如数学表达式需要用$...$,但这个问题可能不涉及太多数学内容。不过如果有例子的话,可能需要用代码块来展示,但用户没有特别提到代码的格式要求,所以可能按照常规的Markdown代码块处理即可。 另外,用户要求用中文回答,所以需要确保整个回答都是中文,并且术语准确。比如“higher-order function”翻译成“高阶函数”是正确的。要避免使用英文术语,除非必要。 现在,我需要检查自己是否正确理解高阶函数的应用场景。例如,数组的map方法接收一个函数作为参数,对每个元素进行处理,返回新数组,这显然是高阶函数的使用。同样,setTimeout接收一个回调函数,这也是高阶函数的例子吗?其实,setTimeout本身是一个函数,它接收函数作为参数,所以从这一点来说,它确实属于高阶函数的使用场景。 然后,关于返回函数的例子,比如函数柯里化,或者创建一个生成特定功能函数的工厂函数。比如,一个乘法函数生成器,接收一个乘数,返回一个函数,该函数将输入乘以这个乘数。这时候,高阶函数返回了另一个函数,这也是典型的高阶函数应用。 还需要提到高阶函数的优势,比如提高代码的复用性、抽象性,使代码更简洁,符合声明式编程范式。比如用map代替for循环,让代码更易读。 然后,可能需要举一些具体的例子。例如,用map将数组每个元素平方,用filter筛选偶数,用reduce计算总和。这些例子能够帮助用户理解高阶函数的具体应用。 另外,可能需要解释回调函数的概念,因为高阶函数常常与回调一起使用。回调函数就是作为参数传递给另一个函数的函数,并在某个时刻被调用。这也是异步编程中常见的模式,比如事件处理、Ajax请求等。 不过要注意不要混淆异步和高阶函数本身的概念。高阶函数的关键在于操作其他函数,而异步只是其中一种使用场景。 然后,思考用户可能的疑问点。比如,高阶函数和普通函数的区别,或者如何自己编写一个高阶函数。可能需要简单说明如何创建接收函数作为参数的函数,或者返回函数的函数。 例如,可以写一个高阶函数,对某个操作进行日志记录,在操作前后输出日志。这样的高阶函数可以接收一个函数作为参数,并返回一个新的函数,该函数在调用原函数前后执行日志记录。这就是装饰器模式的例子,也是高阶函数的应用。 另外,可能需要提到函数式编程的概念,因为高阶函数是函数式编程的重要部分。在JavaScript中,函数是一等公民,可以像变量一样传递,这为高阶函数提供了基础。 最后,确保回答符合用户的要求:结构清晰,逐步解决问题,真实可靠。可能需要分点,如定义、例子、常见高阶函数、优势等部分。 总结回答的结构可能是: 1. 高阶函数的定义 2. 高阶函数的两种形式:接收函数作为参数,返回函数作为结果 3. 常见的高阶函数例子(如数组方法) 4. 自定义高阶函数的例子 5. 高阶函数的优势和应用场景 这样分步骤应该能帮助用户逐步理解。同时,要注意使用中文术语,避免错误,并确保例子正确无误。例如,演示map、filter的使用,或者创建一个简单的高阶函数示例。</think>JavaScript 的高阶函数(Higher-Order Function)是指能够以其他函数作为参数、或返回一个新函数的函数。它是函数式编程的核心概念之一,可提升代码的简洁性、复用性和可读性。以下分步骤说明: --- ### 1. **高阶函数的定义** 高阶函数满足以下任一条件: - **接收函数作为参数**:例如,对数组元素进行操作的函数。 - **返回一个新函数**:例如,通过闭包动态生成特定功能的函数。 --- ### 2. **常见高阶函数示例** #### (1) 接收函数作为参数 JavaScript 数组方法广泛使用高阶函数,例如: - **`map`**:将数组元素映射为新值。 ```javascript const numbers = [1, 2, 3]; const squares = numbers.map(x => x * x); // [1, 4, 9] ``` - **`filter`**:筛选符合条件的元素。 ```javascript const evens = numbers.filter(x => x % 2 === 0); // [2] ``` - **`setTimeout`**:异步执行回调函数。 ```javascript setTimeout(() => console.log("Hello"), 1000); ``` #### (2) 返回函数 - **函数工厂**:生成特定功能的函数。 ```javascript function multiplyBy(n) { return x => x * n; } const double = multiplyBy(2); console.log(double(5)); // 10 ``` - **闭包**:保留外部作用域的变量。 ```javascript function createCounter() { let count = 0; return () => ++count; } const counter = createCounter(); console.log(counter()); // 1 ``` --- ### 3. **自定义高阶函数示例** 假设需要为函数调用添加日志功能: ```javascript function withLogging(fn) { return (...args) => { console.log("函数开始执行"); const result = fn(...args); console.log("函数执行结束"); return result; }; } const add = (a, b) => a + b; const addWithLog = withLogging(add); addWithLog(2, 3); // 输出日志并返回5 ``` --- ### 4. **高阶函数的优势** - **抽象与复用**:将通用逻辑(如遍历、过滤)封装成高阶函数,避免重复代码。 - **声明式编程**:用 `map`、`filter` 替代 `for` 循环,代码更直观。 - **灵活组合**:通过组合多个高阶函数实现复杂逻辑。 --- ### 5. **应用场景** - **数据处理**:操作数组或集合(如筛选、转换、聚合)。 - **异步控制**:回调函数、Promise、`async/await`。 - **装饰器模式**:增强函数功能(如日志、缓存、权限校验)。 --- ### 总结 高阶函数通过操作其他函数,显著提升 JavaScript 的表达能力。理解并熟练使用它,能写出更简洁、模块化的代码,是进阶函数式编程的重要基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值