在JavaScript中尽量不使用eval

yumo6667个月前 (05-21)技术文章42

前言

在修改一个问题的时候,发现在竟然用eval计算数组的和,不知道当时为什么会这样写(有点不过脑子),不过eval尽量不要使用,在MDN有2个不建议使用eval的建议:

  1. 安全性,eval使用与调用者相同的权限执行代码,如跨站脚本攻击(XSS),恶意脚本注入到页面中,从而控制用户的浏览器.
  2. 性能,eval必须调用JavaScript的解释器,在由解释器转为机器码,任意一个eval的使用都会强制浏览器进行冗长的变量名称查找,以确定变量在机器代码中的位置并设置其值.

如果要使用evel,可以使用Function进行替代,在MDN说Function比eval快,在后面的测试中,Function并没有比eval快很多.

示例代码

function generateRandomArray(len) {
    let arr = [];
    for (let i = 0; i < len; i++) {
        let value = Math.floor(Math.random() * len * 10);
        arr.push(value);
    }
    return arr;
}

function test() {
    let sumArr = [];
    let randomArray = generateRandomArray(16);
    for (var i = 0, len = randomArray.length; i < len; i++) {
        //处理其他的逻辑
        sumArr.push(randomArray[i]);
    }
    let expression = sumArr.join('+');
    let sum = eval(expression); //使用eval计算 '1+2'表达式
    console.log(expression);
    console.log(sum);
}

看一下结果:

先说说test函数中有哪些问题:

1) 使用eval计算表达式

2) 使用sumArr数组,多增加内存的使用,计算数组内值的和,没必要增加一个数组.

不使用evel,可以使用那些方式

1) 最直接的方式,直接在for循环中进行计算

2) 使用JavaScript中reduce函数计算.

3) 使用Function代替eval函数计算.

来测试这几种方式,那个性能比较好.

function generateRandomArray(len) {
    let arr = [];
    for (let i = 0; i < len; i++) {
        let value = Math.floor(Math.random() * len * 10);
        arr.push(value);
    }
    return arr;
}

function evalTest(randomArray, testLen) {
    let sum = 0;
    let sumArray = [];
    console.time('eval ' + testLen);
    for (var i = 0, len = randomArray.length; i < len; i++) {
        sumArray.push(randomArray[i]);
    }
    sum = eval(sumArray.join('+')); //使用eval计算表达式
    console.timeEnd('eval ' + testLen);
    console.error('eval:' + sum);
}

function forTest(randomArray, testLen) {
    let sum = 0;
    console.time('for ' + testLen);
    for (var i = 0, len = randomArray.length; i < len; i++) {
        //最简单直接的方式,直接求和运算
        sum += randomArray[i];    
    }
    console.timeEnd('for ' + testLen);
    console.error('for:' + sum);
}

function readuceTest(randomArray, testLen) {
    let sum = 0;
    console.time('reduce ' + testLen);
    sum = randomArray.reduce((previousValue, currentValue) => {
        return previousValue + currentValue
    }, 0);  //使用reduce
    console.timeEnd('reduce ' + testLen);
    console.error('reduce:' + sum);
}

function functionTest(randomArray, testLen) {
    let sum = 0;
    let sumArray = [];
    console.time('function ' + testLen);
    for (var i = 0, len = randomArray.length; i < len; i++) {
        sumArray.push(randomArray[i]);
    }
    //使用Function
    sum = new Function('"use strict"; return ' + sumArray.join('+') + ';')();
    console.timeEnd('function ' + testLen);
    console.error('function:' + sum);
}

function allTest() {
    var testLenArray = [16, 64, 128];
    for (var i = 0, len = testLenArray.length; i < len; i++) {
        let randomArray = generateRandomArray(testLenArray[i]);
        evalTest(randomArray, testLenArray[i]);
        forTest(randomArray, testLenArray[i]);
        readuceTest(randomArray, testLenArray[i]);
        functionTest(randomArray, testLenArray[i]);
    }
}
allTest();

先看看Edge浏览器执行结果:

然后看看Firefox浏览器的执行结果:

通过测试结果得出:

1) 在循环内,直接求和的方式在数组长度不多的情况,性能最好

2) reduce在数组长度相对多之后,性能比for求值性能好

3) Function在性能上和eval半斤八两

个人能力有限,如果您发现有什么不对,请私信我

如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流

相关文章

还在用Python的eval处理用户输入?你的代码可能正在“裸奔”!

凌晨3点,程序员小王被急促的电话惊醒。线上系统突然删光了所有用户订单数据——仅仅因为一段用了eval()的代码。这不是电影情节,而是某电商平台真实的安全事故。今天我们就来深挖这个潜伏在无数Python...

php中assert和eval的详细介绍(代码示例)

本篇文章给大家带来的内容是关于php中assert和eval的详细介绍(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。assert 判断一个表达式是否成立。返回true o...

简单学Python——内置函数9——eval()函数

今天我们学习Python内置的eval()函数。eval()函数解析传递给该函数的表达式,并在程序中运行python表达式(代码)。听起来挺抽象,简单点说,就是eval()接收一个字符串,然后把两边的...

上科大校友研发小推理模型,证明低秩自适应技术强大能力

“我们这篇论文可能是目前唯一一篇在推理模型能力上详细告诉大家到底花了多少钱的论文。”上海科技大学 95 后本科校友、美国南加州大学博士生王上上告诉 DeepTech。近日,他和所在团队打造出一系列名为...

教大模型学数学,总共分几步?

大模型那么聪明,为什么数学题总是做不对、做不会?从答高考数学卷难及格到普通数字比大小出错,大模型总算让大家觉得并非“无所不能”。这一方面让普通人开心,毕竟讲到AI取代人类看起来为时尚早,而另一方面,大...

马斯克推出首个AI大模型:善于讽刺,只训练了两个月,部分超越GPT3.5

成立半年多,xAI发布了首个AI(人工智能)大模型产品:一个善于讽刺的聊天机器人。当地时间11月4日,埃隆·马斯克(Elon Musk)旗下xAI团队发布了首个AI大模型产品Grok。据xAI团队在官...