【函数式编程】高阶函数(JavaScript)

高阶函数(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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值