1. 多个函数集合组合为一个函数集合(JSON)

/**组合多个函数集合为一个
*@param target 返回的函数集合JSON
*@param options 其他要组合的函数集合JSON*/
function mergeFnObjs(target, ...options) {
	const fns = {};
	if(options && options.length>=1)
		for(let callbacks of options){
			if(typeof callbacks != "object") continue;
			for (let name in callbacks) {
				const fn = callbacks[name];
				if(typeof target[name]!='function'){
					//如果原来不是函数,无论是什么都覆盖
					target[name] = fn;
				}else{
					//const argc = fn.length;参数列表长度
					//否则就加如集合中等待合并
					if(fns[name]==null){
						fns[name]=[fn];
					}else{
						fns[name].push(fn);
					}
				}
			}
		}


	//组合函数
	for(const name in fns){
		const fnArr = fns[name];
		const fn0 = target[name];
		function merge(){
			const args = arguments;
			//调用顺序从后往前
			//最后一个里的函数的返回值作为整体的返回值,如果没有依次取前面的
			let ret = null;
			const len = fnArr.length;
			for(let i=len-1;i>=0;i--){
				try {
					const r0 = fnArr[i](...args);
					if(ret==null) ret=r0;
				} catch (error) {
					console.error("cti组合回调函数执行异常!",error);
				}
			}
			try {
				const r0 = fn0(...args);
				if(ret==null) ret=r0;
			} catch (error) {
				console.error("cti组合回调函数执行异常!",error);
			}
			return ret;
		}
		target[name]=merge;
	}
	return target;
}
//测试代码
var a={
	a:function(p){
		const arg = arguments;
		if(arg.length>1)
			console.log("a.a   ",...arguments)
		else
		console.log("a.a   ",p)
	},
	c:function(p){
		console.log("a.c   ",p)
	}
}

var b={
	a:function(p){
		console.log("b.a   ",arguments)
	},
	b:function(p){
		console.log("b.b   ",arguments)
	}
}
var c={
	a:function(p){
		console.log("c.a   ",p)
	}
}

a=mergeFnObjs(a,b,c);
a.a("arg1",2,3);
a.b("arg11");
a.c("arg111",22);

2. 多个函数组合为一个函数

/**多个函数组合为一个函数
*@param target 返回的函数
*@param otherFns 其他要组合的函数
*/
function mergeFns(target, ...otherFns){
	if(otherFns && otherFns.length>=1){
		function merge(){
			const args = arguments;
			//依次调用,将先调用的不为空的返回值作为最终返回值
			let ret = target(...args);
			for(let fn in otherFns){
				cont r0 = fn(...args);
				if(ret==null) ret=r0;
			}
			return ret;
		}
		return merge;
	}else{
		return target;
	}
}
03-08 17:25