如Douglas Crockford的 JavaScript,The Good Parts 所述,将字符串传递给setTimeout
或setInterval
会调用eval()
,应该避免:< / p>
setTimeout('console.log("this uses eval()");', 100);
考虑到这一点,使用内联事件处理程序时会发生同样的事情吗?:
<button onclick="console.log('click!');">Click Me</button>
换句话说,使用内联事件处理程序会在触发事件时产生额外的解析开销,或者在初始文档加载期间使用其他所有内容(例如内联脚本块,标题中的脚本等)完成解析。
答案 0 :(得分:4)
是的,比喻说,确实如此。 页面中的所有 javascript的解析方式与传递给eval()
的代码完全相同。要避免eval()
,主要是因为它比普通代码慢,因为它需要额外的解析。
您可以验证浏览器是否已编译处理程序或重新编译它,至少对于具有不错开发人员工具的浏览器(示例代码使用jQuery,但当然您可以在普通JS中重写它):
<div id="test" onclick="alert('tested')">Click</div>
<script>
console.log(typeof $('#test')[0].onclick);
console.log($('#test')[0].onclick);
</script>
在我的Chrome测试中,会记录以下内容:
Type of handler: function
function onclick(event) {
alert('click')
}
很明显,onclick
属性是编译的function
值。您还可以看到处理程序的额外生成代码,即围绕内联代码的函数。您还可以在处理程序中设置断点并观察堆栈跟踪,以验证其中的任何位置都没有eval
调用。