提早接收部分參數,延遲執行,不當即輸出結果,而是返回一個接受剩餘參數的函數緩存
EXAMPLE 01app
"use strict";
/** * * EXAMPLE 0-1 */
;(() => {
function add_currying() {
console.log(arguments, this);
}
function currying(fn) {
let cache = []
let next = function () {
if (arguments.length > 0) {
let args = [].slice.call(arguments, 0)
cache = cache.concat(args)
return next
} else {
return fn.apply(this, cache) // 看到結果後,明白這裏的this是沒有用的,能夠傳null
}
}
next.empty = function () {
let res = fn.apply(this, cache)
cache = []
return res
}
return next
}
var add = currying(add_currying)
add(1)(2)(3, 4).empty()
//[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4 } { [Function: next] empty: [Function] }
add(2)(5)(7)()
//[Arguments] { '0': 2, '1': 5, '2': 7 } undefined
})()
複製代碼
EXAMPLE 02函數
/** * * EXAMPLE 0-2 */
;( () => {
function add_currying () {
console.log(arguments,this);// [Arguments] { '0': 1, '1': 1, '2': 34, '3': 5 } null
return 1
}
function currying(fn){
let cache = []
let next = function(){
cache = [...cache,...arguments]
return next
}
next.toString = next.valueOf = () => fn.apply(null,cache)
return next
}
var add = currying(add_currying)
console.log(add(1)(1,34,5) + 1); //2
})()
複製代碼
Function.prototype.unCurrying = function(){
let self = this
return function(){
return Function.prototype.call.apply(self,arguments)
}
}
var show = Object.prototype.toString.unCurrying()
console.log(show('23'));
複製代碼
var show = Object.prototype.toString.unCurrying() // ==>
Function.prototype.unCurrying = function(){
let self = this // this ==> Object.prototype.toString
return function(){
return Function.prototype.call.apply(self,arguments)
// ==> Object.prototype.toString.call(arguments)
// 這裏call的this指向被apply方法轉變爲Object.prototype.toString
// 同時執行 toString 而且將toString的this指向轉變爲 arguments[0]
// 最終執行的是 arguments[0].toString
}
}
// 該方式本質上就是將原來必須由對象去點方法的形式改成,方法接受對象做爲參數
複製代碼
其實這與下面的方法沒什麼不一樣ui
var unCurrying = function(fn){
return function(){
return fn.apply(arguments[0],[].slice.call(arguments,1))
}
}
var show2 = unCurrying(Object.prototype.toString)
console.log(show2('23'));
複製代碼
寫了一通,發現反柯里化好像沒什麼道理(小聲BB),不能讓大佬發現個人無知。this
/** * 柯里化應用 * @descript 緩存計算值,重複計算(須要目標值) */
;
(() => {
function currying(v, fn) {
let cache = v
let next = function () {
if (arguments.length > 0) {
let args = [].slice.call(arguments, 0)
cache = fn.call(this, cache, ...arguments)
return next
} else {
let res = cache
cache = v
return res
}
}
next.empty = function () {
let res = cache
cache = v
return res
}
return next
}
function ab_currying(a, b) {
return a + b
}
var ab = currying(0, ab_currying)
console.log(ab(1)(2)(3)()); //6
console.log(ab(4,5)(9)()); // 13
})()
複製代碼
/** * 給定目標值,分別計算 */
;
(() => {
Function.prototype.currying = function () {
let fn = this,
args = arguments
return function () {
return fn.apply(this, [...args, ...arguments])
}
}
function ab(a, b) {
return a + b
}
let test = ab.currying(1)
console.log(test(2)); // 3
console.log(test(3)); // 4
})()
複製代碼
/** * 簡化參數 * @descript 當函數參數中有多個一樣的參數 */
;
(() => {
Function.prototype.currying = function () {
let fn = this,
args = arguments
return function () {
let index = 0,
len = arguments.length,
new_args = [...args]
for (let i = 0, args_len = args.length; i < args_len && len < args_len; i++) {
if (args[i] === undefined) {
new_args[i] = arguments[index++]
}
}
return fn.apply(this, new_args)
}
}
function test_currying(a, b, c) {
console.log(a, b, c);
}
let test = test_currying.currying(1, undefined, 2)
test(10) // 1 10 2
test(100) // 1 100 2
/* let bindClick = document.body.addEventListner.currying('click',undefined,false) bindClick(function(){ console.log(1) }) bindClick(function(){ console.log(2) }) */
})()
複製代碼