在JS里函数非常重要,并且是一等公民。
一等公民的定义
根据维基百科,编程语言中一等公民的概念是由英国计算机学家Christopher Strachey提出来的,时间则早在上个世纪 60 年代,那个时候还没有个人电脑,没有互联网,没有浏览器,也没有 JavaScript。
大概很多人和我一样,没听说过 Christopher Strachey,并且他也只是提出了一等公民的概念,没有给出严格的定义。
关于一等公民,我找到一个权威的定义,来自于一本书《Programming Language Pragmatics》,这本书是很多大学的程序语言设计的教材。
In general, a value in a programming language is said to have first-class status if it can be passed as a parameter, returned from a subroutine, or assigned into a variable.
也就是说,在编程语言中,一等公民可以作为函数参数,可以作为函数返回值,也可以赋值给变量。
函数为第一公民是函数式编程的基础,比如现在的Vue3 CompositionApi就是以函数式编程的运用。
函数允许作为参数
我们看下面的一段代码,calc函数的形参为num1,num2,以及calcFn(计算方法) 此处形参calcFn就是一个作为参数的函数,他也被叫做回调函数(callback)
回调函数(callback)是JavaScript异步编程的基础,其实就是把函数作为函数参数。例如,大家常用的setTimeout函数的第一个参数就是函数
function calc(num1,num2,calcFn){
console.log(calcFn(num1,num2));
}
function add(num1,num2){
return num1 + num2
}
function sub(num1,num2){
return num1 - num2
}
function mul(num1,num2){
return num1 * num2
}
let m = 20
let n = 30
calc(m,n,add)
函数作为返回值
function countNum(count){
return function goodPrice(good){
return count * good
}
}
let price = 300
let countNumOfGood = countNum(0.5)
console.log(countNumOfGood(price));
这是一个典型的商品折扣函数,此处goodPrice函数就被当成了返回值。
高阶函数的定义
把一个函数如果接受另外一个函数作为作为参数,或者该函数会返回另外一个函数作为返回值的函数,那么这个函数就称之为一个高阶函数
常见的高阶函数
filter过滤函数
let arr = [32, 33, 16, 40];
let result = arr.filter((currentValue,index,arr)=>{
return currentValue % 2 == 0
})
console.log(result); //[ 32, 16, 40 ]
filter的英文翻译是过滤器。filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。它并不改变原数组的值。
map映射函数
//map函数
let arr = [4, 9, 16, 25];
let result = arr.map((currentValue,index,arr)=>{
return currentValue * 10
})
console.log(result); //[ 40, 90, 160, 250 ]
find与findIndex
在JavaScript中,find()
和findIndex()
是数组的两个方法。它们都接受一个函数作为参数,并返回数组中满足该函数条件的第一个元素或元素索引。
const arr = [1, 2, 3, 4, 5];
const result = arr.find((element) => element > 3);
console.log(result); // 4
它在找对象数组中特别好用,下面是一个使用场景。
let friends = [
{
name : 'harry',
age:40
},
{
name:'tom',
age:41
},
{
name:'tom',
age:18
}
];
let friendFind = friends.find((item) => {
return item.name === 'harry'
})
console.log(friendFind); //{ name: 'harry', age: 40 }
let friendFindIndex = friends.findIndex((item) => {
return item.name === 'harry'
})
console.log(friendFindIndex); //0
map的中文翻译是映射。map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
reduce累加器函数
reduce函数返回上一次的返回值
let arr = [4, 9, 16, 25];
let total = arr.reduce((preValue,item)=>{
return preValue + item
},0) //从0开始累加(也可以不加)
console.log(total) //54