网站首页 > 知识剖析 正文
前言
在修改一个问题的时候,发现在竟然用eval计算数组的和,不知道当时为什么会这样写(有点不过脑子),不过eval尽量不要使用,在MDN有2个不建议使用eval的建议:
- 安全性,eval使用与调用者相同的权限执行代码,如跨站脚本攻击(XSS),恶意脚本注入到页面中,从而控制用户的浏览器.
- 性能,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半斤八两
个人能力有限,如果您发现有什么不对,请私信我
如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流
猜你喜欢
- 2024-11-17 CSV Parquet Avro:为正确的工作选择合适的工具
- 2024-11-17 JS基础进阶- 同步异步编程和EventLoop底层机制
- 2024-11-17 5个你应该知道的JavaScript技巧,不能错过!
- 2024-11-17 map映射+异步加载 完美过渡 if else
- 2024-11-17 Chrome控制台的一些有用API(chrome控件)
- 2024-11-17 Javascript调试器自编代码及运用(js调试工具和方法如何使用)
- 2024-11-17 NET中的定时器:种类与应用场景(winform定时器)
- 2024-11-17 全栈之路:从一个深拷贝开始循序渐进
- 2024-11-17 localStorage灵魂五问。 5M??10M(灵魂官方网站)
- 2024-11-17 JS中用于跟踪程序执行时间的专用函数,两个同时出现截断时间戳
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)