文章目录
高阶函数(Higher-Order Function):接受函数作为参数并且/或者返回函数作为输出的函数
1. 函数可作为JavaScript的一种数据类型
当一门语言允许函数作为任何其他数据类型使用时,函数被称为一等公民(First Class Citizens)。也就是说,函数可被赋值给变量,作为参数传递,也可被其他函数返回。
存储函数
var fn = () => {} // fn是一个指向函数数据类型的变量
> typeof fn
'function'
> fn
[Function: fn]
> fn()
undefined
传递函数
var tellType = (arg) => {
console.log(typeof arg)
}
tellType(fn)
返回函数
var crazy = () => { return String }
console.log(crazy()("Higher-Order Function"))
// crazy() 返回的是函数引用,并没有执行函数
2. 抽象和高阶函数
通过高阶函数实现抽象
forEach函数
const forEach = (array, fn) => {
for (let i = 0; i < array.length; i++) {
fn(array[i])
}
}
上面的forEach函数抽象出了遍历数组的问题。
forEach([1, 2, 3], (data) => {
// data被作为参数从forEach函数传到当前的函数
})
forEachObject函数
forEachObject抽象出了遍历JavaScript对象的问题
const forEachObject = (obj, fn) => {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
// 以key和value作为参数调用fn
fn(property, obj[property])
}
}
}
let object = {a: 1, b: 2}
forEachObject(object, (k, v) => {
console.log(k + ":" + v)
})
unless函数
unless除非;predicate 谓语
// 接受一个断言,如果predicate为false,则调用fn()
const unless = (predicate, fn) => {
if (!predicate) fn()
}
forEach([1,2,3,4,5,6,7], (number) => {
unless((number % 2), () => {
console.log(number, "is even")
})
})
times函数
要从0-100中获取偶数如何做呢
const times = (times, fn) => {
for (let i = 0; i < times; i++) {
fn(i)
}
}
// 输出0-100的偶数
times(100, (n) => {
unless((n % 2), () => {
console.log(n, "is even")
})
})
3. 真实的高阶函数
every函数
const every = (array, fn) => {
let results = true;
for (let i = 0; i < array.length; i++) {
results = results && fn(array[i])
if (results == false) return results
}
return results
}
console.log(every([NaN, NaN, NaN], isNaN)) // true
console.log(every([NaN, NaN, 1], isNaN)) // false
some函数
只要有一个为true就是true
const some = (arr, fn) => {
let results = false;
for (const value of arr) {
results = results || fn(value)
if (results == true) return results
}
return results
}
console.log(some([NaN, NaN, NaN], isNaN)) // true
console.log(some([NaN, NaN, 1], isNaN)) // true
sort函数
var fruit = ["cherries", "apples", "bananas"]
fruit.sort()
console.log(fruit)
compare函数的骨架
function compare(a, b) {
if (根据某种排序标准a < b) {
return -1
}
if (根据某种排序标准a > b) {
return 1
}
return 0
}
var people = [
{firstname: "aa", lastname: "cc"},
{firstname: "cc", lastname: "aa"},
{firstname: "bb", lastname: "bb"}
]
根据firstname排序
people.sort((a, b) => {
return (a.firstname < b.firstname) ? -1 : (a.firstname > b.firstname) ? 1 : 0
})
console.log(people)
sortBy函数
允许用户基于传入的属性对对象数组排序
const sortBy = (property) => {
return (a, b) => {
return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0
}
}
sortBy返回的函数正好是sort函数的输入参数
people.sort(sortBy("lastname"))
console.log(people)