柯里化
- 當一個函數(shù)有多個參數(shù)的時候先傳遞一部分參數(shù)調(diào)用它(這部分參數(shù)以后永遠不變)
- 然后返回一個新的函數(shù)接收剩余參數(shù)冗尤,返回結(jié)果
//科里化演示
function checkAge (age){
let min = 18;
return age >= min;
}
//普通的純函數(shù)
function checkAge (min,age){
return age >= min;
}
console.log(checkAge(18,25))
console.log(checkAge(18,26))
console.log(checkAge(18,27))
console.log(checkAge(18,28))
console.log(checkAge(24,29))
console.log(checkAge(24,29))
function checkAge (min){
return function(age){
return age >= min;
}
}
let checkAge18 = checkAge(18);
let checkAge20 = checkAge(20);
console.log(checkAge18(20));
console.log(checkAge20(24));
//es6寫法
let checkAgeEs6 = min => (age => age >= min);
let checkAgeEs618 = checkAgeEs6(18);
let checkAgeEs620 = checkAgeEs6(20);
console.log(checkAgeEs618(20));
console.log(checkAgeEs620(24));
//當函數(shù)有多個參數(shù)的時候改造為使用一個函數(shù)傳入部分參數(shù)并讓這個函數(shù)返回新的函數(shù)裂七,新的函數(shù)接收剩余參數(shù)并返回處理結(jié)果
tips: 當函數(shù)有多個參數(shù)的時候改造為使用一個函數(shù)傳入部分參數(shù)并讓這個函數(shù)返回新的函數(shù)仓坞,新的函數(shù)接收剩余參數(shù)并返回處理結(jié)果.
lodash中的柯里化方法
- curry(function)
- 功能: 創(chuàng)建一個函數(shù)扯躺,該函數(shù)接收一個或多個function的參數(shù),如果function所需要的參數(shù)都被提供則執(zhí)行function 返回執(zhí)行的結(jié)果倍啥,否則繼續(xù)返回該函數(shù)并等待接收剩余參數(shù)
- 參數(shù): 需要柯里化的函數(shù)
- 返回值: 柯里化后的函數(shù)
//lodash 中的 curry 基本使用
const _ = require("lodash");
//一個參數(shù)叫一元函數(shù) 2個叫二元函數(shù) 3個叫三元函數(shù)
function getSum(a,b,c) {
return a + b + c;
}
//柯里化把多元函數(shù) 轉(zhuǎn)化為一元函數(shù)
//curry
const curried = _.curry(getSum);
console.log(curried(1)(2)(3));
console.log(curried(1)(2,3));
console.log(curried(1,2)(3));
//柯里化案例
//案例1 判斷一個字符串中有沒有空白字符
''.match(/\s+/g);
//匹配所有數(shù)組
''.match(/\d+/g);
//普通
function match(reg,str){
return str.match(reg);
}
//柯里化
const curryMatch = _.curry(function(reg,str){
return str.match(reg);
});
const haveSpace = curryMatch(/\s+/g);
const haveNumber = curryMatch(/\d+/g);
console.log(haveSpace(" 1 2 3 4 5 6"))
console.log(haveNumber(" 1 2 3 4 5 6"))
//查找數(shù)組中空白字符元素
const filter = _.curry(function(func,array){
return array.filter(func);
})
const findSpace = filter(haveSpace);
//es6寫法
const filterEs6 = _.curry((func,array) => array.filter(func));
const findSpaceES6 = filter(haveSpace);
console.log(findSpace(['aaaabbbb','a b']));//[ 'a b' ]
console.log(findSpaceES6(['aaaab bbb','a b']));//[ 'aaaab bbb', 'a b' ]
柯里化原理
一個 柯里化的函數(shù)首先會接受一些參數(shù)虽缕,接受了這些參數(shù)之后蒲稳,該函數(shù)并不會立即求值氮趋,而是繼續(xù)返回另外一個函數(shù)伍派,剛才傳入的參數(shù)在函數(shù)形成的閉包中被保存起來。待到函數(shù)被真正需要求值的時候剩胁,之前傳入的所有參數(shù)都會被一次性用于求值
//科里化演示
function checkAge (age){
let min = 18;
return age >= min;
}
//普通的純函數(shù)
function checkAge (min,age){
return age >= min;
}
console.log(checkAge(18,25))
console.log(checkAge(18,26))
console.log(checkAge(18,27))
console.log(checkAge(18,28))
console.log(checkAge(24,29))
console.log(checkAge(24,29))
function checkAge (min){
return function(age){
return age >= min;
}
}
let checkAge18 = checkAge(18);
let checkAge20 = checkAge(20);
console.log(checkAge18(20));
console.log(checkAge20(24));
//es6寫法
let checkAgeEs6 = min => (age => age >= min);
let checkAgeEs618 = checkAgeEs6(18);
let checkAgeEs620 = checkAgeEs6(20);
console.log(checkAgeEs618(20));
console.log(checkAgeEs620(24));
//當函數(shù)有多個參數(shù)的時候改造為使用一個函數(shù)傳入部分參數(shù)并讓這個函數(shù)返回新的函數(shù)诉植,新的函數(shù)接收剩余參數(shù)并返回處理結(jié)果
lodash中的科里化
//lodash 中的 curry 基本使用
const _ = require("lodash");
//一個參數(shù)叫一元函數(shù) 2個叫二元函數(shù) 3個叫三元函數(shù)
function getSum(a,b,c) {
return a + b + c;
}
//柯里化把多元函數(shù) 轉(zhuǎn)化為一元函數(shù)
//curry
const curried = _.curry(getSum);
console.log(curried(1)(2)(3));
console.log(curried(1)(2,3));
console.log(curried(1,2)(3));
//柯里化案例
//案例1 判斷一個字符串中有沒有空白字符
''.match(/\s+/g);
//匹配所有數(shù)組
''.match(/\d+/g);
//普通
function match(reg,str){
return str.match(reg);
}
//柯里化
const curryMatch = _.curry(function(reg,str){
return str.match(reg);
});
const haveSpace = curryMatch(/\s+/g);
const haveNumber = curryMatch(/\d+/g);
console.log(haveSpace(" 1 2 3 4 5 6"))
console.log(haveNumber(" 1 2 3 4 5 6"))
//查找數(shù)組中空白字符元素
const filter = _.curry(function(func,array){
return array.filter(func);
})
const findSpace = filter(haveSpace);
//es6寫法
const filterEs6 = _.curry((func,array) => array.filter(func));
const findSpaceES6 = filter(haveSpace);
console.log(findSpace(['aaaabbbb','a b']));//[ 'a b' ]
console.log(findSpaceES6(['aaaab bbb','a b']));//[ 'aaaab bbb', 'a b' ]
柯里化原理模擬
function curry (func) {
return function curriedFn(...args) {
// 判斷實參和形參的個數(shù) 函數(shù).length 這種寫法獲取函數(shù)參數(shù)長度
//如果實參的參數(shù)少于形參的長度則返回一個函數(shù)繼續(xù)接受參數(shù)
//形成閉包保留args 參數(shù)依次疊加 直到 大于或等于形參 不滿足條件 調(diào)用 func(...args)
if (args.length < func.length) {
return function (...args2) {
return curriedFn(...args.concat(args2))
}
}
//如果函數(shù)的實參和形參個數(shù)相同直接調(diào)用需要柯里化函數(shù)并返回結(jié)果
return func(...args)
}
}
柯里化總結(jié):
- 柯里化可以讓我們給一個函數(shù)傳遞較少的參數(shù)得到一個已經(jīng)記住了某些固定參數(shù)的新函數(shù)
- 這是一種對函數(shù)參數(shù)的'緩存'
- 讓函數(shù)變的更靈活,讓函數(shù)的粒度更小
- 可以把多元函數(shù)轉(zhuǎn)換成一元函數(shù)昵观,可以組合使用函數(shù)產(chǎn)生強大的功能