# TypeScript 函数式编程
# 1. 函数作为一等公民(与 number 同值):
# 变量类型可以是函数
let a:(a: number, b: number) => number
a = (a:number, b:number)=>(a+b)
# 值(literal)可以是函数
let add = function(a: number, b:number):number {
return a + b
}
console.log(add(1, 2)) //3
# 对象的字段可以是函数
const emp1 = {
name: 'hedon',
salary: 10000,
increaseSalary: function(p: number){
this.salary += p
},
}
# 函数的参数可以是函数
let a = [5, 2, 1, 11, 23, 4, 5, 0, 64, 8]
// 按照字典顺序排序
a.sort()
console.log(a) // [0, 1, 11, 2, 23, 4, 5, 5, 64, 8]
// 按照数值大小排序
// 函数
a.sort((a: number, b: number) => {
return a-b
})
// lambda: 箭头函数
a.sort((a: number, b: number) => a-b)
a.sort((a, b) => a -b)
a.sort(() => )
console.log(a) // [0, 1, 2, 4, 5, 5, 8, 11, 23, 64]
# 函数的返回值可以是函数
function createComparetor(smallFirst: boolean): (a:number, b:number) => number{
if(smallFirst){
return (a,b) => a-b
}else{
return (a,b) => b-a
}
}
console.log(createComparetor(true)(1,2)) //-1
console.log(createComparetor(false)(1,2)) //1
# 2. 高阶函数
- 函数的参数可以是函数;
- 函数的返回值可以是函数;
function loggingComparer(f: (a:number, b:number) => number) {
return (a: number, b: number) =>{
console.log('logging: ', a, b)
return f(a, b)
}
}
console.log(loggingComparer((a: number, b :number) => (a-b))(1,2))
console.log(loggingComparer((a: number, b :number) => (a+b))(1,2))
console.log(loggingComparer((a: number, b :number) => (a*b))(1,2))
# 3. 函数闭包
非闭包版本:
- 需要维护全局变量 compCount
let compCount = 0
// 比较器
function createComparer(p: {smallerFirst: boolean}) {
if(p.smallerFirst){
return (a:number, b:number) => a - b
}else{
return (a:number, b:number) => b - a
}
}
// 比较器增强器
function loggingComparer(comp: (a: number, b:number) => number) {
return (a:number, b: number) => {
console.log(`comparing: {a} with {b}`)
compCount ++
return comp(a, b)
}
}
let a = [4,2,6,23,11,9,0,-2,34]
// 比较
const comp = createComparer({smallerFirst: true})
a.sort(loggingComparer(comp))
console.log(a)
console.log(`compare count: ${compCount}`)
闭包版本:
// 比较器
function createComparer(p: {smallerFirst: boolean}) {
if(p.smallerFirst){
return (a:number, b:number) => a - b
}else{
return (a:number, b:number) => b - a
}
}
// 比较器增强器
function loggingComparer(
logger :(a: number, b:number) => void,
comp: (a: number, b:number) => number) {
return (a:number, b: number) => {
logger(a,b)
return comp(a, b)
}
}
// 函数闭包
function processArray(a: number[]){
let compCount = 0
// logger 是一个闭包,可以延长 compCount 的生命周期
// compCount 是一个自由变量
const logger = (a: number, b: number) => {
console.log(`compare ${a} with ${b}`)
compCount ++
}
// 比较
const comp = createComparer({smallerFirst: true})
a.sort(loggingComparer(logger,comp))
// 输出比较次数
console.log(`compare count: ${compCount}`)
}
let a = [4,2,6,23,11,9,0,-2,34]
// 比较
processArray(a)
console.log(a)
# 4. 部分应用函数
示例 1:
// 部分函数应用
function partiallyApply(
// 双参数函数
f: (a:number, b:number) => number,
a: number) {
// 返回一个单参数函数
// 这样你可以先给我 a
// 返回再通过我这个返回的函数,后面有了 b 再给我
return (b: number) => f(a,b)
}
// 加法
function add(a: number, b:number):number {
return a + b
}
// 现在只有 a,还没有拿到 b
let a = 10
const partFunc = partiallyApply(add, a)
// 现在有了 b 了
let b = 3
const result = partFunc(b)
// 结果
console.log(result) // 13
示例 2:
// 判断一个数字是不是好数字
function isGoodNumber(gooFactor: number, v: number){
return v % gooFactor === 0
}
// 过滤器
function filterArray(a: number[], f: (v: number) => boolean){
return a.filter(f)
}
// START CONFIG
const GOOD_FACTOR = 2
// END CONFIG
const a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
// 部分应用函数:
// 1. 已经有了 GOOD_FACTOR,但是还缺少 v
// 2. 这个时候可以用部分应用函数:我先给了 GOOD_FACTOR
// 3. 然后再借一个 v,它会自动从 a 中拿出每一个元素
console.log(filterArray(a, (v) => isGoodNumber(GOOD_FACTOR, v)))