eval函数是一种强大而简单的动态生成代码的方法,那么有什么注意事项呢?
当前回答
如果您发现代码中使用了eval(),请记住“eval()是邪恶的”。
这 function接受任意字符串,并将其作为JavaScript代码执行。当代码进入时 问题是事先知道的(不是在运行时确定的),没有理由使用 eval()。 如果代码是在运行时动态生成的,通常有更好的方法 在没有eval()的情况下实现目标。 例如,只用方括号来表示 访问动态属性更好更简单:
// antipattern
var property = "name";
alert(eval("obj." + property));
// preferred
var property = "name";
alert(obj[property]);
使用eval()也有安全隐患,因为您可能正在执行代码(用于 示例来自网络),已被篡改。 这是处理Ajax请求的JSON响应时常见的反模式。 在这些情况下 最好使用浏览器内置的方法来解析JSON响应 当然这是安全有效的。对于不支持原生JSON.parse()的浏览器,可以这样做 使用来自JSON.org的库。
同样重要的是要记住,将字符串传递给setInterval(), setTimeout(), Function()构造函数在很大程度上类似于使用eval(),因此 应该避免。
在幕后,JavaScript仍然需要计算和执行 作为编程代码传递的字符串:
// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);
// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);
使用新的Function()构造函数类似于eval(),应该尝试一下 与护理。它可能是一个强大的结构,但经常被误用。 如果你一定要的话 使用eval(),你可以考虑使用new Function()代替。
这是一个很小的潜力 好处,因为在new Function()中求值的代码将在本地函数中运行 范围,因此在被求值的代码中使用var定义的任何变量都不会变成 自动全局。
防止自动全局变量的另一种方法是将 Eval()调用直接函数。
其他回答
如果您发现代码中使用了eval(),请记住“eval()是邪恶的”。
这 function接受任意字符串,并将其作为JavaScript代码执行。当代码进入时 问题是事先知道的(不是在运行时确定的),没有理由使用 eval()。 如果代码是在运行时动态生成的,通常有更好的方法 在没有eval()的情况下实现目标。 例如,只用方括号来表示 访问动态属性更好更简单:
// antipattern
var property = "name";
alert(eval("obj." + property));
// preferred
var property = "name";
alert(obj[property]);
使用eval()也有安全隐患,因为您可能正在执行代码(用于 示例来自网络),已被篡改。 这是处理Ajax请求的JSON响应时常见的反模式。 在这些情况下 最好使用浏览器内置的方法来解析JSON响应 当然这是安全有效的。对于不支持原生JSON.parse()的浏览器,可以这样做 使用来自JSON.org的库。
同样重要的是要记住,将字符串传递给setInterval(), setTimeout(), Function()构造函数在很大程度上类似于使用eval(),因此 应该避免。
在幕后,JavaScript仍然需要计算和执行 作为编程代码传递的字符串:
// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);
// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);
使用新的Function()构造函数类似于eval(),应该尝试一下 与护理。它可能是一个强大的结构,但经常被误用。 如果你一定要的话 使用eval(),你可以考虑使用new Function()代替。
这是一个很小的潜力 好处,因为在new Function()中求值的代码将在本地函数中运行 范围,因此在被求值的代码中使用var定义的任何变量都不会变成 自动全局。
防止自动全局变量的另一种方法是将 Eval()调用直接函数。
Eval并不总是邪恶的。有些时候,这是非常合适的。
然而,eval在当前和历史上都被那些不知道自己在做什么的人过度使用。不幸的是,这包括编写JavaScript教程的人,在某些情况下,这确实会产生安全后果——或者,更常见的是,简单的错误。所以,我们在eval上加的问号越多越好。任何时候你使用eval你都需要检查你正在做的事情,因为你可能会用一种更好,更安全,更干净的方式来做。
举一个非常典型的例子,设置id存储在变量'potato'中的元素的颜色:
eval('document.' + potato + '.style.color = "red"');
如果上面这类代码的作者对JavaScript对象工作的基本原理有所了解,他们就会意识到可以使用方括号来代替字面上的点名称,从而消除了eval的需要:
document[potato].style.color = 'red';
...这更容易阅读,也更少潜在的错误。
(但是,那些/真正/知道自己在做什么的人会说:
document.getElementById(potato).style.color = 'red';
这比直接从文档对象中访问DOM元素更可靠。)
我相信这是因为它可以从字符串执行任何JavaScript函数。使用它可以使人们更容易向应用程序中注入恶意代码。
主要是,维护和调试要困难得多。就像goto一样。您可以使用它,但它会使发现问题变得更加困难,对稍后可能需要进行更改的人来说也更加困难。
随着带有JavaScript编译器的下一代浏览器问世,这可能会成为一个更大的问题。通过Eval执行的代码在这些新浏览器上的表现可能不如JavaScript的其他部分。应该有人来做侧写。
推荐文章
- 在数组中获取所有选中的复选框
- 如何为Firebase构建云函数,以便从多个文件部署多个函数?
- 如何发送推送通知到web浏览器?
- AngularJS:工厂和服务?
- js:将一个组件包装成另一个组件
- 父ng-repeat从子ng-repeat的访问索引
- JSHint和jQuery: '$'没有定义
- 模仿JavaScript中的集合?
- 用JavaScript验证电话号码
- 如何在HTML5中改变视频的播放速度?
- 谷歌地图API v3:我可以setZoom后fitBounds?
- ES6/2015中的null安全属性访问(和条件赋值)
- 与push()相反;
- JS字符串“+”vs concat方法
- AngularJS使用ng-class切换类