網(wǎng)站首頁 編程語言 正文
一. 柯里化函數(shù)實現(xiàn):
1. 使用函數(shù)的length+arguments+apply的相關知識
var slice = Array.prototype.slice
var curry = function (fn) {
// 拿到fn參數(shù)之后的參數(shù)
var args = slice.call(arguments, 1)
return _curry.apply(this, [fn, fn.length].concat(args))
}
function _curry(fn, len) {
// 獲取fn, len之外的其他參數(shù)
var oArgs = slice.call(arguments, 2);
return function () {
var args = oArgs.concat(slice.call(arguments))
if (args.length >= len) {
return fn.apply(this, args)
}
else {
return _curry.apply(this, [fn, len].concat(args))
}
}
}
2. 使用函數(shù)的length + 擴展運算符...? + apply的知識:
var curry = function (fn, ...arg1) {
const len = fn.length
return _curry.apply(this, [fn, len, ...arg1])
}
function _curry(fn, len, ...rest1) {
return function (...rest2) {
var args = [...rest1, ...rest2]
if (args.length >= len) {
return fn.apply(this, args)
}
else {
return _curry.apply(this, [fn, len].concat(args))
}
}
}
實例運用:
測試計算總和的功能:
function calcSum(num1, num2, num3) {
return num1 + num2 + num3
}
var calcSum2 = function (...args) {
// const arr = Array.from(arguments);
const arr = Array.prototype.slice.call(arguments, 0);
// const arr = Array.of(...args);
let sum = 0;
return arr.reduce((obj, cur) => {
sum = obj + cur
return sum
}, sum)
}
const log = console.log
var len1 = 1
var calcSumCurry = _curry(calcSum2, 4)
log(calcSumCurry(3, 4, 5, 6))// 18
log(calcSumCurry(3)(4)(5)(6))//18
log(calcSumCurry(3)(4, 5)(6))//18
var calcSumCurry = curry(calcSum, 3)
log(calcSumCurry(4, 5))//12
log(calcSumCurry(4)(5))//12
每次只要在最后執(zhí)行空參函數(shù), 就開始計算, 下一次重新開始
function _curry(fn, len) {
var oArgs = slice.call(arguments, 2);
return function () {
var args = oArgs.concat(slice.call(arguments));
if (arguments.length === 0) {
if (args.length >= len) {
return fn.apply(this, args);
}
return console.warn('curry: 參數(shù)長度不足')
}
return _curry.apply(this, [fn, len].concat(args))
}
}
var calcSum2 = function (...args) {
// const arr = Array.from(arguments);
const arr = Array.prototype.slice.call(arguments, 0);
// const arr = Array.of(...args);
let sum = 0;
return arr.reduce((obj, cur) => {
sum = obj + cur
return sum
}, sum)
}
const log = console.log
var calcSumCurry = _curry(calcSum2, 4)
// 每次都從頭開始算
log(calcSumCurry(3, 4, 5, 6)())// 18
log(calcSumCurry(3)(4)(5)(6)())//18
log(calcSumCurry(3)(4, 5)(6)())//18
log(calcSumCurry(3)(4, 5)()) // curry: 參數(shù)長度不足
想要一直累加:
var slice = Array.prototype.slice
function curry(fn, len0) {
const curArgs = []
const len = len0 || fn.length
return function () {
if (arguments.length === 0) {
if (curArgs.length >= len) return fn.apply(this, curArgs)
return console.warn('curry: 參數(shù)長度不足')
}
Array.prototype.push.apply(curArgs, [].slice.call(arguments));
return arguments.callee;
}
}
var calcSum2 = function (...args) {
// const arr = Array.from(arguments);
const arr = Array.prototype.slice.call(arguments, 0);
// const arr = Array.of(...args);
let sum = 0;
return arr.reduce((obj, cur) => {
sum = obj + cur
return sum
}, sum)
}
const log = console.log
var calcSumCurry = curry(calcSum2, 4)
log(calcSumCurry(3, 4, 5)())// curry: 參數(shù)長度不足
log(calcSumCurry(4)(5)())// 21
嚴格模式下callee會報錯, 可以改成:
'use strict'
var slice = Array.prototype.slice
function curry(fn, len0) {
const curArgs = []
const arg2 = []
const len = len0 || fn.length
let tag = 'start'
return function start () {
if (arguments.length === 0) {
if (curArgs.length >= len) {
if(tag === 'end') return console.warn('curry: 參數(shù)長度不足, 請核對參數(shù)后重試')
return fn.apply(this, curArgs)
}
tag = 'end'
// 只有第一次執(zhí)行計算的時候才會判斷參數(shù)長度是否足夠
return console.warn('curry: 參數(shù)長度不足')
}
Array.prototype.push.apply(curArgs, [].slice.call(arguments));
return start;
}
}
var calcSum2 = function (...args) {
const arr = Array.prototype.slice.call(arguments, 0);
let sum = 0;
return arr.reduce((obj, cur) => {
sum = obj + cur
return sum
}, sum)
}
const log = console.log
var calcSumCurry = curry(calcSum2, 4)
log(calcSumCurry(3, 4, 5)()) // curry: 參數(shù)長度不足
log(calcSumCurry(4)(5)()) // 參數(shù)長度不足, 請核對參數(shù)后重試
柯里化log方法:
var slice = Array.prototype.slice;
var curry = function (fn, length) {
var args = slice.call(arguments, 2)
return _curry.apply(this, [fn, length || fn.length].concat(args))
};
function _curry(fn, len) {
var oArgs = slice.call(arguments, 2);
return function () {
var args = oArgs.concat(slice.call(arguments));
if (args.length >= len) {
return fn.apply(this, args);
} else {
return _curry.apply(this, [fn, len].concat(args))
}
}
}
function log(logLevel, msg) {
console.log(`${logLevel}:${msg}:::${Date.now()}`)
}
//柯里化log 方法
const curryLog = curry(log);
const debugLog = curryLog("debug");
const errLog = curryLog("error");
//復用參數(shù)debug
debugLog("testDebug1");//debug:testDebug1:::1696145622354
debugLog("testDebug2");//debug:testDebug2:::1696145622360
//復用參數(shù)error
errLog("testError1");//error:testError1:::1696145622360
errLog("testError2");//error:testError2:::1696145622360
二. 非柯里化的實現(xiàn)方式:
1. 偏函數(shù)
偏函數(shù)求和:
// 偏函數(shù)
function partial(fn) {
// 接受fn之外的參數(shù)
const args = [].slice.call(arguments, 1)
return function () {
// 接收剩余參數(shù)
const newArgs = args.concat([].slice.call(arguments));
return fn.apply(this, newArgs)
}
}
function calcSum(...args) {
const arr = [...args]
let sum = 0;
return arr.reduce((obj, cur) => {
sum = obj + cur
return sum
}, sum)
}
// 偏函數(shù)是固定一部分參數(shù)(一個或者多個參數(shù)), 將一個N元函數(shù)轉換為一個N-X函數(shù)
const pCalcSum = partial(calcSum, 10);
console.log(pCalcSum(11, 12))//33
2. 反柯里化
1.?反柯里化方法的幾種寫法:
Function.prototype.unCurry=function() {
var self = this
return function() {
return Function.prototype.call.apply(self, arguments)
}
}
Function.prototype.unCurry=function() {
return this.call.bind(this)
}
Function.prototype.unCurry=function() {
return (...args) => this.call(...args)
}
2. 反柯里化實例運用:
1) 克隆數(shù)組
function unCurry1(fn) {
return function(context) {
// this換成傳入的參數(shù)context, context之外的參數(shù)作為apply的剩余參數(shù)
return fn.apply(context, Array.prototype.slice.call(arguments, 1));
}
}
Function.prototype.unCurry = function () {
const self = this
return function() {
return Function.prototype.call.apply(self, arguments)
}
}
// 復制數(shù)組
var clone = Array.prototype.slice.unCurry()
var a = [1, 2, 3]
var b = clone(a);
console.log('a == b', a === b); // 除非引用一樣, 否則都是false
console.log(a, b);//[ 1, 2, 3 ] [ 1, 2, 3 ]
var slice = [].slice
var clone = unCurry1(slice)
var a = [1, 2, 3]
var b = clone(a);
console.log('a == b', a === b); // 除非引用一樣, 否則都是false
console.log(a, b);//[ 1, 2, 3 ] [ 1, 2, 3 ]
2) 生成類數(shù)組
function unCurry1(fn) {
return function(context) {
// this換成傳入的參數(shù)context, context之外的參數(shù)作為apply的剩余參數(shù)
return fn.apply(context, Array.prototype.slice.call(arguments, 1));
}
}
Function.prototype.unCurry = function () {
const self = this
return function() {
return Function.prototype.call.apply(self, arguments)
}
}
var push = Array.prototype.push.unCurry();
var obj = {}
// console.log(Array.prototype.slice.call({0:1, length: 1}, 0))//[1]
push(obj, 4, 5, 6); // 對象變成了類數(shù)組
console.log(obj)//{ '0': 4, '1': 5, '2': 6, length: 3 }
var obj = {}
unCurry1([].push)(obj, 7, 8, 9, 10)
console.log(obj)//{ '0': 7, '1': 8, '2': 9, '3': 10, length: 4 }
原文鏈接:https://blog.csdn.net/qq_42750608/article/details/133446241
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-03-28 用python實現(xiàn)九九乘法表實例_python
- 2022-04-21 Mybatis - tk.mybatis deleteByPrimaryKey無法正確識別主鍵
- 2022-02-24 React插槽使用方法_React
- 2022-10-23 Android?手寫RecyclerView實現(xiàn)列表加載_Android
- 2022-07-13 nginx-1.20*安裝check模塊
- 2022-04-11 K8S部署Kafka界面管理工具(kafkamanager)方法詳解_云其它
- 2022-10-02 OpenCV黑帽運算(BLACKHAT)的使用_python
- 2022-03-26 C語言輸出孿生素數(shù)的實現(xiàn)示例_C 語言
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支