函数柯里化应用

函数柯里化

把使用多个参数的函数转换成一系列使用一个参数的函数,返回接受余下参数并且返回结果的新函数;(也就是:只传递一个部分参数来调用这个函数,让他返回一个新函数去处理余下的参数)

日常应用

  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}
发布了66 篇原创文章 · 获赞 13 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/haoyanyu_/article/details/99305317