函数柯里化应用 迷南。 2021-10-18 14:46 231阅读 0赞 ### 函数柯里化 ### 把使用多个参数的函数转换成一系列使用一个参数的函数,返回接受余下参数并且返回结果的新函数;(也就是:只传递一个部分参数来调用这个函数,让他返回一个新函数去处理余下的参数) #### 日常应用 #### 1. 动态创建函数:(dom元素添加事件监听是,根据兼容性判断生成不同的函数) //只在函数第一次执行时判断一次,用到了闭包和立即执行函数 const addEvent = (function(){ if(window.addEventListener) { return function(el, type, fn, capture){ el.addEventListener(type, fn, capture) } } else if(window.attachEvent) { return function(el, type, fn) { el.attachEvent('on' + type, fn) } } })() 1. 延迟计算:(调用方法传入参数,不计算最后结果,当不传任何值以后再计算) const adds = function(...args) { return args.reduce(function(a, b){ return a + b}) } function currying2(func) { let sum = []; return function result() { var arg = [].slice.call(arguments); if(arg.length == 0) { var res = func.apply(null,sum) console.log('method2:' + res) return res; } else { sum.push(...arg) return result } } } let sum2 = currying2(adds); let addCurryTwo = sum2(1,2)(3); addCurryTwo(2)(); // 8 1. 延时计算(指定传入的参数数量,满足后执行计算) function currying1(fn, length) { //fn.length获取的是函数形参的个数,第一个具有默认值之前的参数个数 length = length || fn.length; // 第一次是获取参数个数,之后是获取每次剩余参数个数 return function (...args) { //返回一个函数 if(args.length >= length){ // 当获取了全部数量的参数后,执行fn方法 // console.log(args); return fn.apply(this, args); } else { return currying1(fn.bind(this, ...args), length - args.length) // 不满足函数个数,递归调用currying1方法, } } } // 计算方法 const fn = currying1(function(a, b, c) { console.log([a, b, c]); }); fn("a", "b")("c") // ["a", "b", "c"] fn("a")("b")("c") // ["a", "b", "c"] fn("a")("b", "c") // ["a", "b", "c"] 1. 参数复用 判读一个数据的类型 function isType(type){ return function(arg){ var res = Object.prototype.toString.call(arg); console.log(res) return res == "[object "+ type +"]" } } var res = isType('String')(null); 调用toString可以获取每个对象的类型,但是不同的对象有不同的toString的实现,所以要调用Object.prototype.toString()方法。 可以通过bind方法扩展,通过参数复用,实现一个toStr方法: //使用函数的call方法指定一个this值,然后bind返回一个新函数,始终将Object.prototype.toString作为传入的参数 const toStr = Function.prototype.call.bind(Object.prototype.toString); toStr([1,2,3]) ; //'[object Array]' -------------------- **bind方法** * 返回一个指定上下文的函数 * 传入bind的第二个以及之后的参数,加上绑定函数运行时本身的参数, 按照顺序作为原函数的参数来调用原函数 var value = 2; var foo = { value: 1 }; function bar(name,age) { return { value:this.value, name, age } } var bindFoo = bar.bind(foo, 'tommy').bind(foo, 23); console.log(bindFoo()) // {value: 1, name: 'tommy', age: 23}
还没有评论,来说两句吧...