eval函数是一种强大而简单的动态生成代码的方法,那么有什么注意事项呢?
当前回答
编辑:正如Benjie的评论所建议的,这似乎不再是chrome v108的情况,似乎chrome现在可以处理已计算脚本的垃圾收集。
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
垃圾收集
浏览器的垃圾收集不知道被评估的代码是否可以从内存中删除,所以它只是一直存储它,直到页面被重新加载。 如果你的用户只是在你的页面上停留很短的时间,这不是太糟糕,但这可能是一个webapp的问题。
下面是演示该问题的脚本
https://jsfiddle.net/CynderRnAsh/qux1osnw/
document.getElementById("evalLeak").onclick = (e) => {
for(let x = 0; x < 100; x++) {
eval(x.toString());
}
};
像上面代码这样简单的代码会导致存储少量内存,直到应用程序死亡。 当被赋值的脚本是一个巨大的函数,并且在间隔时间调用时,情况会更糟。
其他回答
这是一篇谈论eval的好文章,以及它如何不是一种邪恶: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/
I’m not saying you should go run out and start using eval() everywhere. In fact, there are very few good use cases for running eval() at all. There are definitely concerns with code clarity, debugability, and certainly performance that should not be overlooked. But you shouldn’t be afraid to use it when you have a case where eval() makes sense. Try not using it first, but don’t let anyone scare you into thinking your code is more fragile or less secure when eval() is used appropriately.
我相信这是因为它可以从字符串执行任何JavaScript函数。使用它可以使人们更容易向应用程序中注入恶意代码。
这可能存在安全风险,它具有不同的执行范围,并且效率非常低,因为它为代码的执行创建了一个全新的脚本环境。更多信息请参见这里:eval。
不过,它非常有用,适度使用可以添加许多很好的功能。
需要记住的一件事是,您可以经常使用eval()在其他受限制的环境中执行代码——阻塞特定JavaScript函数的社交网站有时可以通过在eval块中分解它们来愚弄它们
eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');
因此,如果你想运行一些JavaScript代码,否则它可能是不允许的(Myspace,我看着你…),那么eval()可能是一个有用的技巧。
然而,由于上面提到的所有原因,你不应该在你自己的代码中使用它,在那里你有完全的控制权——这是没有必要的,最好把它归到“棘手的JavaScript hacks”架子上。
如果你知道你在什么环境中使用它,它并不一定那么糟糕。
如果您的应用程序使用eval()从XMLHttpRequest返回到您自己的站点的某个JSON中创建一个对象,该对象是由受信任的服务器端代码创建的,那么这可能不是问题。
不可信的客户端JavaScript代码无论如何也做不了那么多。只要你执行eval()的对象来自一个合理的源,就没问题。