在JavaScript中尽量不使用eval

yumo6666个月前 (05-21)技术文章37

前言

在修改一个问题的时候,发现在竟然用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()

在 Python 中,eval() 是一个强大但危险的函数,用于执行字符串形式的 Python 表达式。以下是深度解析:一、基础用法result = eval(expression, globals=...

清华团队深度实证:RL 真能让大模型进化吗?能力边界仍被基座“锁死”!

大数据文摘出品强化学习(RL)真的能让大模型获得超越基础模型的新推理能力吗?近日,清华大学LeapLab团队联合上海交大,发布了一篇题为《Does Reinforcement Learning Rea...

越聪明越会撒谎?OpenAI推理模型o3/o4-mini幻觉率翻倍,嘴还很硬

OpenAI 最新发布的推理 AI 模型 o3 和 o4-mini 在性能上又创新高,就在大家期待它能进一步提升日常工作的生产力时,许多用户却发现,它们的幻觉率却比前代模型要高了不少。据 OpenAI...

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

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

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

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

苹果为什么要用小模型?

编辑:alan【新智元导读】WWDC 2024上,苹果推出了Apple Intelligence,向大家展示了如何开发、训练出功能强大、快速且节能的模型,如何根据特定用户需求进行微调,以及如何评估模型...