01函数式编程、高阶函数、闭包

函数式编程

  • 很多库可以辅助进行函数式开发:lodash,underscore,ramda
  • 函数式编程可以抛弃 this
  • vue3 也是越来多使用函数式编程,如 composition
  • 方便测试,并行处理

概念

函数式编程(Functional Programming, FP),FP 是编程范式之一,我们常听说的编程范式还有面向过程 编程、面向对象编程。

  • 面向对象编程的思维方式:把现实世界中的事物抽象成程序世界中的类和对象,通过封装、继承和 多态来演示事物事件的联系
  • 函数式编程的思维方式:把现实世界的事物和事物之间的联系抽象到程序世界(对运算过程进行抽 象)
    • 程序的本质:根据输入通过某种运算获得相应的输出
    • x -> f(联系、映射) -> y,y=f(x)
    • 函数式编程中的函数指的不是程序中的函数(方法),而是数学中的函数即映射关系,例如:y = sin(x),x 和 y 的关系
    • 相同输入始终得到相同输出(纯函数)

总结就是:函数式编程用来描述数据(函数)之间的映射

案例:

// 非函数式
let num1 = 1;
let num2 = 2;
let sum = num1 + num2;
// 函数式
function sum (n1,n2) {
    return n1+n2;
}
sum (1,2)

函数式编程就是对运算过程的抽象

函数是一等公民

  • 可以存储在变量中;
  • 可以作为参数;
  • 可以作为返回值;

在 JavaScript 中函数就是一个普通的对象 (可以通过 new Function() ),我们可以把函数存储到变量/ 数组中,它还可以作为另一个函数的参数和返回值,甚至我们可以在程序运行的时候通过 new Function(‘alert(1)’) 来构造一个新的函数。

  • 把函数赋值给变量
// 把函数赋值给变量
let fn = function() {
    console.log('hello word')
}
fn()
// 一个示例
const BlogController = {
	index(posts) {
      return views.index(posts)
    }
}
// 优化
const BlogController = {
	index: Views.index
}
  • 函数是一等公民,是学习高阶函数和柯里化等的基础;

高阶函数

  • 可以把函数作为参数传递给另一个函数
  • 可以把函数作为另一个函数返回值

函数作为参数

// 函数作为参数
// 模拟 forEach:遍历数组每一个元素,并对每个元素进行处理
function forEach(array,fn) {
    for(var i = 0; i < array.length; i++) {
    	fn(array[i])
	}
}
let arr = [1,2,3,4];
forEach(arr,function(v) {
	console.log(v)
});
// 模拟 filter:过滤数组中满足条件的元素
function filter(array,fn) {
    let result = [];
    for(let value of array) {
        if (fn(value)) {
            result.push(value)
        }
    }
    return result;
}
let arr = [11,12,3,2,5];
let r = filter(arr,function(v) {
    return v%2;
})
console.log(r)

函数作为返回值

function makeFn() {
    let msg = 'hello word function';
    return function() {
        console.log(msg)
    }
}
const fn = makeFn();
fn();
makeFn()()

模拟 once:对一个函数只执行一次

意义:订单多次点击只执行一次

function once(fn) {
    let done = false;
    return function() {
        if (!done) {
            done = true
            return fn.apply(this,arguments)
        }
    }
}
let pay = once(function(money) {
    console.log(money)
})
pay(5)
pay(5)
pay(5)

意义

  • 运算过程抽像成函数,然后在任何地方可以重用,这样可以不需要关注细节,只需要关注我们的目标就好了;
  • 高阶函数就是用来抽象通用的问题;

常用的高阶函数

  • forEache
  • map
  • filter
  • every
  • some
  • find/findIndex
  • reduce
  • sort

模拟 map

// 对数组中每个元素遍历并处理,并将处理结果存储到一个新数组返回
const map = (array,fn) => {
    let result = [];// 新数组
    for(let value of array) {
        result.push(fn(value))
    }
    return result
}
// 测试
let arr = [1,2,3,4]
arr = map(arr,v => v * v)
map 函数参数是个函数,它是高阶函数,不管可以对数组中每个元素求平方,也可以通过传入不同函数,对数组中任意元素操作;

模拟 every

数组方法:用来判断数组中每个元素是否匹配我们指定的条件,这个条件是可变的;
const every = (array, fn) => {
	let result = true;
	for(let value of array) {
        result = fn(value)
        if (!result) {
            // 当有一个元素不满足则跳出循环
            break;
        }
	}
	return result;
}
// 测试
let arr = [2,12,11,13,15];
// 判断数组中每个元素是否都大于 10
let r = every(arr,v => v > 10)

模拟 some

检测数组中元素,是否有有一个满足指定条件
const some = (array,fn) => {
	let result = false;
	for(let value of array) {
        result = fn(value);
        if (result) {
            return
        }
	}
	return result;
}
// 测试
let arr = [2,3,5,7,11];
// 判断数组中每个元素是否有偶数
let r = every(arr,v => v > 10)

闭包

  • 函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包
    • 可以在另一个作用域中调用一个函数内部函数,并访问该函数作用域中的成员

本质

​ 函数执行时会放在一个执行栈上当函数执行完毕会从执行栈上移除,但是堆上的作用域成员因为被外部应用不能释放,因此内部函数依然可以访问外部函数成员。

案例

求幂:
Math.pow(4,2) // 求 4 的 2 次方
Math.pow(5,2)
// 生成求平方和三次方函数
function makePower(power) {
    return funnction (number) {
        return Math.pow(number,power)
    }
}
// 求平方
let power2 = MakePower(2);
// 求三次方
let power3 = MakePower(3);
console.log(power2(4))
console.log(power3(4))

案例二

// 求员工公司(基本工资加绩效工资)
// getSalary(12000,2000)
// getSalary(15000,3000)
// getSalary(15000,4000)
// 为不同级别员工生成一个去求工资函数
fucntion makeSalary(base) {
	return function (performance) {
        return base + performace;
	}
}
let salaryLevel1 = makeSalary(12000);
let salaryLevel2 = makeSalary(15000);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值