JavaScript客户端计算器:如何创建映射运算符的工厂函数(避免使用eval)
不用eval实现运算符映射的工厂函数
嘿,这个问题问得太对了——eval确实是个要尽量避开的东西,不光有安全风险,代码可读性和维护性也差。其实用一个简单的对象映射表就能完美解决你的需求,而且做法非常直观。
核心思路
我们可以把每个运算名称和对应的函数关联起来,放在一个对象里,然后工厂函数只需要根据传入的名称,从这个对象里取出对应的函数返回就行。
具体实现
首先先保留你已经写好的运算函数(或者直接把函数定义在映射对象里,看你习惯):
// 先定义好各个运算函数 const add = (a, b) => a + b; const subtract = (a, b) => a - b; const multiply = (a, b) => a * b; const divide = (a, b) => a / b; // 创建一个映射表:键是运算名称,值是对应的函数 const operationMap = { add, subtract, multiply, divide }; // 工厂函数实现 function createOperation(opName) { // 先做个校验,避免传入不存在的运算名称 if (!operationMap[opName]) { throw new Error(`抱歉,不支持名为 ${opName} 的运算`); } // 返回对应的运算函数 return operationMap[opName]; }
怎么用
调用工厂函数的时候,直接传入运算名称字符串就行:
// 获取加法函数 const addFunc = createOperation("add"); console.log(addFunc(5, 3)); // 输出 8 // 获取除法函数 const divideFunc = createOperation("divide"); console.log(divideFunc(10, 2)); // 输出 5
进阶优化:直接在映射表定义函数
如果你的运算函数都比较简短,也可以直接把函数写在映射对象里,省去单独定义的步骤,代码更紧凑:
const operationMap = { add: (a, b) => a + b, subtract: (a, b) => a - b, multiply: (a, b) => a * b, divide: (a, b) => a / b }; function createOperation(opName) { if (!operationMap[opName]) { throw new Error(`Unsupported operation: ${opName}`); } return operationMap[opName]; }
为什么这个方法比eval好
- 安全:不会执行任意字符串代码,避免了注入风险;
- 易维护:以后要加新运算,比如取模
mod,只需要在operationMap里加一行mod: (a, b) => a % b就行; - 可读性高:一眼就能看出各个运算名称对应的逻辑,调试也方便。
内容的提问来源于stack exchange,提问作者Colin
相关产品推荐
相关产品推荐

