如何简化自定义JS框架中makeInstruction函数的多参数处理?
简化JS框架中指令函数的实现技巧
我正在开发一个JS框架,需要创建并存储函数到Map的数组中(支持启用/禁用或加入requestAnimationFrame循环,这部分暂不讨论)。目前的指令函数写法比较繁琐,想请教有没有更简洁的实现方式:
- 能否自动设置多参数函数的b、c等参数,不用手动从数组里提取?
- 有没有实用技巧简化
makeInstruction和readInstruction的逻辑,以及内部函数的编写?
原代码如下:
// 原代码存在语法错误,已标注修正点 function isReal(v) { // 原错误:缺少v,修正为 return v !== null && v !== undefined ? true : false; } //-- 核心函数 function makeInstruction(name, instr, args = null) { // 假设isString是判断字符串的自定义函数,这里替换为原生写法 if (typeof name === 'string' && instr instanceof Function) { return args === null ? [name, instr] : [name, instr, Array.isArray(args) ? args : [args]]; } } function readInstruction(instr) { let tx = 'FUNCTION readInstructions:\n'; if (Array.isArray(instr)) { if (typeof instr[0] === 'string') { if (instr[1] instanceof Function && instr.length < 4) { let res, ln = instr.length; // saylog(instr.length); // 假设为自定义日志函数 switch (ln) { case 3: //-- 函数带参数 res = instr[1](instr[2]); tx += "NAME" + instr[0] + (isReal(res) ? ' result: ' + res : ''); break; case 2: //-- 函数无参数 res = instr[1](); tx += 'NAME' + instr[0] + (isReal(res) ? ' result: ' + res : ''); break; default: tx += 'ERROR default length ' + ln; break; } // console.log(tx); return res; } } } return; } //-- 使用示例(修正原代码笔误) let ins = makeInstruction('someFunction', function() { return new Date().toLocaleString(); // 原错误:new Date后需加() }) console.log(readInstruction(ins)) let ins1Arg = makeInstruction('FN1arg', function(a) { return 'hello ' + a }, 'world') console.log(readInstruction(ins1Arg)) // 原笔误:redInstruction -> readInstruction let ins1ArgInt = makeInstruction('FN1argInt', function(a) { return 10 + parseInt(a) }, 5) console.log(readInstruction(ins1ArgInt)) // 原笔误:ins1console.log -> console.log // 可行但繁琐的写法 let withArgs=makeInstruction('someFunc', function(a){ return (a[0]+a[1])*a[2]}, [1,2,10] ) console.log( readInstruction( withArgs ) )//-- 30 // 尝试过的无效写法 // let withArgs=makeInstruction('someFunc', function(a,b,c){ arguments=a; return (a+b)*c}, [1,2,10] ) // console.log( readInstruction( withArgs ) )//-- NaN // 最终写法但未简化多少 let withArgs2 = makeInstruction('someFunc', function(a) { arguments = a; return (arguments[0] + arguments[1]) * arguments[2] }, [1, 2, 10]) console.log(readInstruction(withArgs2)) //-- 30
核心优化方案:让参数自动展开
问题的核心是readInstruction调用函数时,直接把数组作为单个参数传入,导致多参数函数无法直接接收。我们可以修改readInstruction,让它把参数数组展开后传递给目标函数,这样定义函数时就能直接声明多个参数,不用手动处理数组。
优化后的完整代码
// 简化isReal:!= null 同时排除null和undefined function isReal(v) { return v != null; } // 用剩余参数简化参数收集,支持多参数直接传入 function makeInstruction(name, instr, ...args) { if (typeof name === 'string' && typeof instr === 'function') { return [name, instr, ...args]; } } // 提前退出减少嵌套,用解构和参数展开简化逻辑 function readInstruction(instr) { // 非法情况直接返回,避免多层嵌套 if (!Array.isArray(instr) || typeof instr[0] !== 'string' || typeof instr[1] !== 'function') { return; } const [name, fn, ...args] = instr; const res = fn(...args); // 关键:自动展开参数数组 // 简化日志拼接 const tx = `FUNCTION readInstructions:\nNAME${name}${isReal(res) ? ` result: ${res}` : ''}`; // console.log(tx); return res; }
优化后的使用示例
// 无参数函数:用箭头函数更简洁 const ins = makeInstruction('someFunction', () => new Date().toLocaleString()); console.log(readInstruction(ins)); // 单参数函数 const ins1Arg = makeInstruction('FN1arg', (a) => `hello ${a}`, 'world'); console.log(readInstruction(ins1Arg)); // hello world // 多参数函数:直接声明多个参数,无需手动处理数组 const withArgs = makeInstruction('someFunc', (a, b, c) => (a + b) * c, 1, 2, 10); console.log(readInstruction(withArgs)); // 30 // 也支持传入数组批量传参(用展开运算符转成单个参数) const withArrayArgs = makeInstruction('someFunc', (a, b, c) => (a + b) * c, ...[1, 2, 10]); console.log(readInstruction(withArrayArgs)); // 30
其他实用技巧
- 简化参数处理:
makeInstruction使用剩余参数...args,直接收集所有传入的参数,无需手动判断是否为数组,同时支持单个或多个参数传入。 - 提前退出减少嵌套:
readInstruction先判断非法情况直接返回,避免多层if嵌套,代码结构更清晰。 - 解构赋值提升可读性:用
const [name, fn, ...args] = instr直接提取指令的各个部分,比索引访问更直观。 - 箭头函数简化写法:定义指令函数时用箭头函数,比普通函数更简洁(无需this绑定时优先使用)。
内容的提问来源于stack exchange,提问作者jean3xw
相关产品推荐
相关产品推荐

