重学前端之重学前端
作者:互联网
重学前端
文章目录
更新日期:10-31
第一次更新:10-31
大前端
开发方向:BFF(中间层)开发、泛客户端开发、传统Web技术的深入
JavaScript
1、函数式编程
尽可能的重用函数
2、高阶函数
概念:将函数作为参数传递给另一个函数
函数作为参数:将函数变得更灵活
函数作为返回值:闭包,柯里化
// 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} RMB`)
})
pay(5)
pay(5)
pay(5)
pay(5)
高阶函数的意义:抽象可以帮我们屏蔽细节,只需要关注与我们的目标;高阶函数是用来抽象通用的问题
3、常用的高阶函数
map
const map = (array, fn) => {
let results = []
for (let value of array) {
results.push(fn(value))
}
return results
}
every:检测数组中的元素是否都满足指定条件
const every = (array, fn) => {
let result = true
for (let value of array) {
result = fn(value)
if (!result) {
break
}
}
return result
}
some:检测数组中的元素是否有一个满足指定条件
const some = (array, fn) => {
let result = false
for (let value of array) {
result = fn(value)
if (result) {
break
}
}
return result
}
4、闭包
一个作用域访问另一个作用域变量换一种说法从一个作用域中访问函数内部的函数并且在这一个函数中可以访问到外部函数的成员
作用:延长内部成员作用范围,当外部作用域对内部变量有引用,内存空间就不会被释放
闭包的本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被外部引用而不能被释放,因此内部函数依然可以访问外部函数的成员(函数套函数,这里的内部指的是函数里面函数的作用域)
闭包发生的时候外部函数会从调用栈上移除掉,但是跟闭包相关的变量会被缓存下来
扩展学习:断点 f11
call stack:函数调用栈
anonymous:匿名函数
scope:作用域
global:全局作用域
local:局部作用域
closure:闭包
5、纯函数
纯函数:相同的输入始终要得到相同的输出,没有任何可观察的副作用
纯函数与不纯函数对比:
slice:返回数组中指定部分,不会改变原数组
splice:对数组进行操作并返回该数组,会改变原数组
纯函数库:Lodash
纯函数的优势:
- 可缓存
- 因为纯函数对相同的输入始终有相同的结果,所以可以把纯函数的结果缓存起来
memoize方法缓存返回值,是一个纯函数
- 可测试
- 纯函数让测试更简单
- 并行处理
- 在多线程环境下并行操作共享的内存数据很可能会出现意外情况
- 纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数 (Web Worker)
6、柯里化
1、柯里化基础
1、解决硬编码问题
- 概念
- 当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)
- 然后返回一个新的函数接收剩余的参数,返回结果
// 柯里化
function checkAge (min) {
return function (age) {
return age >= min
}
}
let checkAge18 = checkAge(18)
let checkAge20 = checkAge(20)
checkAge18(24)
checkAge18(20)
// ES6 写法
let checkAge = min => (age => age >= min)
说明:ES6写法,首先传入一个参数min,因为要返回另一个函数,所以用小括号扩起,age作为内部函数的参数,通过箭头函数写法返回对应的结果
2、Lodash中的柯里化
可以传入一个参数也可以传入多个参数,传入一个参数可以生成一个新的函数
const _ = require('lodash')
// 要柯里化的函数
function getSum (a, b, c) {
return a + b + c
}
// 柯里化后的函数
let curried = _.curry(getSum)
// 测试
curried(1, 2, 3)
curried(1)(2)(3)
curried(1, 2)(3)
3、柯里化案例
使用柯里化生成具备特定功能的函数
const _ = require('lodash')
// 要柯里化的函数
function getSum (a, b, c) {
return a + b + c
}
// 柯里化后的函数
let curried = _.curry(getSum)
// 测试
curried(1, 2, 3)
curried(1)(2)(3)
curried(1, 2)(3)
4、Loadsh中的柯里化实现原理
Array.from将伪数组转化为数组
function curry (func) {
return function curriedFn (...args) {
// 判断实参和形参的个数
if (args.length < func.length) {
return function () {
return curriedFn(...args.concat(Array.from(arguments)))
}
}
// 实参和形参个数相同,调用 func,返回结果
return func(...args)
}
}
5、柯里化总结
- 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
- 柯里化使用闭包,对函数参数的’缓存’
- 让函数变的更灵活,让函数的粒度更小
- 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能
7、函数组合
- 函数组合 (compose):如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间
过程的函数合并成一个函数- 函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果
- 函数组合默认是从右到左执行
// 组合函数
function compose (f, g) {
return function (x) {
return f(g(x))
}
}
function first (arr) {
return arr[0]
}
function reverse (arr) {
return arr.reverse()
}
// 从右到左运行
let last = compose(first, reverse)
console.log(last([1, 2, 3, 4]))
- Lodash中的组合函数:flow() 、flowRight()
flowRight的使用
const _ = require('lodash')
const toUpper = s => s.toUpperCase()
const reverse = arr => arr.reverse()
const first = arr => arr[0]
const f = _.flowRight(toUpper, first, reverse)
console.log(f(['one', 'two', 'three']))
组合函数原理模拟
疑问:useState保存的变量和let保存变量的区别
ire(‘lodash’)
const toUpper = s => s.toUpperCase()
const reverse = arr => arr.reverse()
const first = arr => arr[0]
const f = _.flowRight(toUpper, first, reverse)
console.log(f([‘one’, ‘two’, ‘three’]))
组合函数原理模拟
疑问:useState保存的变量和let保存变量的区别
标签:function,重学,return,函数,前端,let,柯里化,const 来源: https://blog.csdn.net/wingchiehpih/article/details/121071776