携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
众所周知eval(),会将传入进去的字符串当作js代码执行。eval('9 + 6')将会输出15。
使用场景
eval是存在于window对象上的一个属性函数,它可以将传入的字符串当作代码执行。而不是字符串时,就会直接返回。eg: eval('0 + 1')输出1、eval(new Object(1))输出Number{1}也就是数字对象。由于执行字符串的特点。我们可以在项目中使用动态字符串eval的形式,来解决动态调用。案例如代码说明中所示。
隐患
由于eval执行字符串的缘故,在底层实现时,eval函数会读取上下文作用域。暴露作用域的同时,eval函数也具有同执行者相同的权限。这样的话eval就可以如同拥有者去修改任意内容,这对安全有极大的隐患。此外执行效率慢是另一大问题。由于eval强大的执行功能依赖于js解析器进行解析。这同其他js语法比起来开销就大了很多。此外数据类型转化后,还要重新生成代码。所以开销造成的慢是eval带来的性能隐患。
替代方案
好在不使用eval我们仍然能实现执行字符串的功能。这里需要用到另一个全局属性Function,我们可以通过该属性也是构造函数,去生成函数在执行。例如:eval('9 + 6')、我们可以替换成 new Function('9 + 6')()
代码说明
可以用于根据字段执行不同逻辑的场景。(也就是动态调用问题)
import { Button } from 'antd';
function demo(props) {
const { calculate, value1, value2 } = props; // calculate 可以是 加减乘除(add subt mult divi )
const add = () => {
return value1 + value2;
}
const subt = () => {
return value1 - value2;
}
const mult = () => {
return value1 * value2;
}
const divi = () => {
return value1 + value2;
}
const updateValue = () => {
eval(`${calculate}`)
}
return <div>
<Button onClick={updateValue}></Button>
</div>
}
结束语
通过本文,我们梳理了eval可以使用的场景、存在的隐患问题、以及替代方案。并通过代码示例阐述了动态调用下的好处。最后还是希望大家尽量避免用到eval,非要使用时也一定要用Funciton去代替。
我这个人走得很慢,但是我从不后退。——亚伯拉罕·林肯