Web前端之动态执行JavaScrip、微信小程序无法使用eval和Function的解决办法、字符串表达式、字符串运算、数学计算、parseFloat、Function、pop
Web前端之动态执行JavaScrip、微信小程序无法使用eval和Function的解决办法、字符串表达式、字符串运算、数学计算、parseFloat、Function、pop
四种方式动态执行JavaScript
function exec(code, key) {
switch (key) {
case 1:
// eval是同步运行
// 同步,当前作用域
eval(code);
break;
case 2:
// 异步执行
// 异步,全局作用域
setTimeout(code, 0);
break;
case 3:
// 同步,全局作用域
const script = document.createElement('script');
script.innerHTML = code;
document.body.appendChild(script);
break;
case 4:
// 同步,全局作用域
// let fn = new Function(code);
// fn();
new Function(code)();
break;
default:
console.log('出错啦');
break;
}
}
exec("console.log('方式一');", 1);
// 方式一
exec("console.log('方式二');", 2);
// 方式二
exec("console.log('方式三');", 3);
// 方式三
exec("console.log('方式四');", 4);
// 方式四
使用Function进行数学运算
function calculateExpression(str) {
try {
return new Function('return ' + str)();
} catch (error) {
throw new Error(`'${str}' not the correct expression.`);
}
}
console.log(calculateExpression('2+3*4/2*3'));
// 20
console.log(calculateExpression('(2+3)*4/2*3'));
// 30
console.log(calculateExpression('2+k*4/2'));
// '2+k*4/2' not the correct expression.
解决微信小程序无法使用eval和Function进行计算的问题
/**
*
* @param {String} str 运算表达式
* @returns 运算结果
*/
function calculateExpression(str) {
// 运算符栈
const operators = [];
// 操作数栈
const values = [];
// 定义运算符的优先级
const precedence = {
'+': 1,
'-': 1,
'*': 2,
'/': 2
};
/**
* 辅助函数,用于执行运算
* @param {*} operators 运算符栈
* @param {*} values 操作数栈
*/
function applyOperator(operators, values) {
const operator = operators.pop();
const b = values.pop();
const a = values.pop();
switch (operator) {
case '+':
values.push(a + b);
break;
case '-':
values.push(a - b);
break;
case '*':
values.push(a * b);
break;
case '/':
values.push(a / b);
break;
default:
console.log('出错啦');
break;
}
}
for (let i = 0; i < str.length; i++) {
const char = str[i];
// 如果是数字,解析整个数字
if (!isNaN(char)) {
let num = parseFloat(char);
while (i + 1 < str.length && !isNaN(str[i + 1])) {
num = num * 10 + parseFloat(str[i + 1]);
i++;
}
values.push(num);
} else if (char === '(') {
// 如果是左括号,将其推入运算符栈
operators.push(char);
} else if (char === ')') {
// 如果是右括号,将栈顶运算符应用于运算数,直到遇到左括号为止
while (
operators.length > 0 &&
operators[operators.length - 1] !== '('
) applyOperator(operators, values);
// 弹出左括号
operators.pop();
} else if (char in precedence) {
// 如果是运算符
while (
operators.length > 0 &&
precedence[char] <= precedence[operators[operators.length - 1]]
) applyOperator(operators, values);
operators.push(char);
}
}
// 处理剩余的运算符
while (operators.length > 0) applyOperator(operators, values);
// 最终结果位于操作数栈的顶部
return values[0];
}
console.log(calculateExpression('6+3*2-(10-8)+6/3+3'));
// 15
console.log(calculateExpression('(6+3)*2-10-(8+1)/3+3'));
// 8
console.log(calculateExpression('6+3*2-10-8+6/3+3'));
// -1
eval
W3SCHOOL
eval()函数计算或执行参数。
如果参数是表达式,则eval()计算表达式。如果参数是一个或多个JavaScript语句,则eval()执行这些语句。
MDN
eval()函数会将传入的字符串当做JavaScript代码进行执行。
一个表示JavaScript表达式、语句或一系列语句的字符串。表达式可以包含变量与已存在对象的属性。
返回字符串中代码的返回值。如果返回值为空,则返回undefined。
eval()是全局对象的一个函数属性。
eval()的参数是一个字符串。如果字符串表示的是表达式,eval()会对表达式进行求值。如果参数表示一个或多个JavaScript语句,那么eval()就会执行这些语句。不需要用eval()来执行一个算术表达式:因为JavaScript可以自动为算术表达式求值。
如果你以字符串的形式构造了算术表达式,那么可以在后面用eval()对它求值。例如,假设你有一个变量x,你可以通过将表达式的字符串值(例如3 * x + 2)赋值给一个变量,然后在你的代码后面的其他地方调用eval(),来推迟涉及x 的表达式的求值。
如果eval()的参数不是字符串, eval()会将参数原封不动地返回。在下面的例子中,String构造器被指定,而eval()返回了String对象而不是执行字符串。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)