4

正如 Douglas Crockford 在JavaScript,The Good Parts中提到的,将字符串传递给setTimeoutsetInterval调用eval(),应该避免:

setTimeout('console.log("this uses eval()");', 100);

考虑到这一点,使用内联事件处理程序时是否会发生同样的事情,像这样?:

<button onclick="console.log('click!');">Click Me</button>

换句话说,当事件被触发时,使用内联事件处理程序是否会产生额外的解析开销,或者是在初始文档加载期间完成的解析以及其他所有内容(例如内联脚本块、标题中的脚本等)。

4

1 回答 1

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调用。

于 2012-09-16T21:07:14.763 回答