[深刻01] 执行上下文
[深刻02] 原型链
[深刻03] 继承
[深刻04] 事件循环
[深刻05] 柯里化 偏函数 函数记忆
[深刻06] 隐式转换 和 运算符
[深刻07] 浏览器缓存机制(http缓存机制)
[深刻08] 前端安全
[深刻09] 深浅拷贝
[深刻10] Debounce Throttle
[深刻11] 前端路由
[深刻12] 前端模块化
[深刻13] 观察者模式 发布订阅模式 双向数据绑定
[深刻14] canvas
[深刻15] webSocket
[深刻16] webpack
[深刻17] http 和 https
[深刻18] CSS-interview
[react] Hooks前端
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CIvue
[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程react
// x是绑定this后传入slice函数的参数
将add(1,2,3)转化成curryAdd(1)(2)(3)
需求: 将add(1,2,3)转化成curryAdd(1)(2)(3)
缺点:只能处理3个参数的状况,不能处理任意多个参数的状况,毫无扩展性
function curryAdd(a) {
return function(b) {
return function(c) {
return a+b+c
}
}
}
const res = curryAdd(1)(2)(3)
console.log(res, 'res1')
复制代码
处理任意多个参数相加
1. 处理相加逻辑的代码,只是在没有参数时才会执行,其余部分都在处理怎么收集全部参数,会多一次没有参数的调用
2. 相加逻辑能够单独抽离
function curryAdd() {
let params_arr = [] // 用于收集全部实参
function closure() {
const args = Array.prototype.slice.call(arguments) // 每次调用闭包函数传入的实参,能够是多个
if (args.length) {
params_arr = params_arr.concat(args)
// concat返回一个拼接事后的新数组,不改变原数组
return closure
// 若是还有参数,则继续返回闭包函数,则继续继续传参调用
}
return params_arr.reduce((total, current) => total + current)
// 若是没有再传入参数,则相加全部传入的参数,缺点是要多一次没有参数的调用
}
return closure // 第一次调用curryAdd返回的闭包
}
const fn = curryAdd()
const res = fn(1,2)(3)(4)()
console.log(res, 'res'); // 10
复制代码
function add(a,b,c,d,e) {
return Array.prototype.slice.call(arguments).reduce((total, current) => total + current)
// 注意:这里拿到的是实参的实际个数,即实参可能大于形参,当实参 (大于等于) 形参时,执行相加
}
function curryAdd(fn) {
let paramsArr = []
const paramsMaxLength = fn.length // function.length返回函数的形参个数,预期的参数个数为最大参数个数,即相加执行条件
function closure() {
const args = Array.prototype.slice.call(arguments)
paramsArr = paramsArr.concat(args)
if (paramsArr.length < paramsMaxLength) {
return closure
}
// 当参数个数 大于等于 最大的指望个数,即形参的个数时,执行相加函数
return fn.apply(this, paramsArr)
}
return closure
}
const fn = curryAdd(add)
const res = fn(1,2,3)(4)(5,6)
console.log(res, 'res');
复制代码
function add() {
return Array.from(arguments).reduce((total, current) => total + current)
}
function currentAdd(fn) {
let paramsArr = []
function closure() { // 该闭包函数只负责收集参数,处理相加能够在闭包上挂载新的方法getSum
const args = Array.from(arguments)
paramsArr = paramsArr.concat(args)
return closure
}
closure.getSum = function() {
return fn.apply(this, paramsArr) // getSum负责计算,利用了闭包中的变量paramsArr
}
return closure
}
const fn = currentAdd(add)
const resAdd = fn(1)(2,3)
const res = resAdd.getSum(); // 该方法的缺点就是须要单独再调用getSum函数
console.log(res, 'res')
复制代码
function add (a, b) {
return a + b
}
function partial (fn) {...}
const addPartial = partial(add, 1) // ------------------ 实现固定一部分参数1
const res = addPartial(2) // 3 -------------------------- 只传一部分参数 2
复制代码
bind方法绑定this指向,同时也能够传入fn的部分和所有参数,并返回一个新函数,新函数能够传入参数做为fn的剩余参数
function add(a,b,c,d) {
return a+b+c+d
}
function partail() {
const params = Array.prototype.slice.call(arguments)
const fn = params.shift() // 删除数组第一个元素,返回该元素,改变原数组
return fn.bind(this, ...params)
// 该params执行shift后已经改变\
// params数组展开后的全部成员,都会做为fn的参数
// 而且bind返回的新函数还能够传参
}
const fn = partail(add, 1, 2) // 固定了 1,2两个参数
const res = fn(3,4) // 除了固定的参数,剩下的参数在这里传入
console.log(res, 'res')
复制代码
function add(a,b,c,d) {
return Array.from(arguments).reduce((total, current) => total + current)
// 相加实参
// 由于实参可能大于形参
}
function partialAdd(fn) {
let paramsFixed = Array.from(arguments).slice(1)
// 除去fn的剩余参数
// 注意:该方法和curry很类似,current第一调用是不须要传fn参数的,声明的是空数组,而在partial中须要传固定的参数
const paramsMaxLength = fn.length // 形参个数
function closure() {
const args = Array.from(arguments)
paramsFixed = paramsFixed.concat(args)
if (paramsFixed.length < paramsMaxLength) {
return closure
}
return fn.apply(this, paramsFixed) // 大于等于时
}
return closure
}
const fn = partialAdd(add, 2)
const res = fn(3)(4)(5)
console.log(res, 'res') // 14
复制代码
指将上次的(计算结果)缓存起来,当下次调用时,若是遇到相同的(参数),就直接返回(缓存中的数据)
function memoize(fn) {
const cache = {}
return function() {
const key = Array.prototype.join.call(arguments, ',')
if (key in cache) {
return cache[key]
}
return cache[key] = fn.apply(this, arguments)
}
}
复制代码
个人简书:www.jianshu.com/p/eb583d764…webpack