Javascript 语句对性能的影响
好的,在过去的48个小时里,我已经看到了足够多的人提到过这一点,我需要把它作为一个问题来问。在“”(2012)中,它所说的与它在上所说的一样: 不建议使用with语句,因为它可能是源代码 容易混淆的bug和兼容性问题 然而,Zakas的书也指出(没有进一步的实质性阐述),“出于性能原因,[不应该]使用它们”。这个问题显然“非常糟糕”,在Javascript 语句对性能的影响,javascript,with-statement,Javascript,With Statement,好的,在过去的48个小时里,我已经看到了足够多的人提到过这一点,我需要把它作为一个问题来问。在“”(2012)中,它所说的与它在上所说的一样: 不建议使用with语句,因为它可能是源代码 容易混淆的bug和兼容性问题 然而,Zakas的书也指出(没有进一步的实质性阐述),“出于性能原因,[不应该]使用它们”。这个问题显然“非常糟糕”,在Strict模式下,ECMAScript不允许使用语句 这真的是出于性能原因吗?或者,是因为人们无法忍受他们 如果部分原因实际上是由于性能,那么它们如何以及为什么
Strict
模式下,ECMAScript不允许使用语句
这真的是出于性能原因吗?或者,是因为人们无法忍受他们
如果部分原因实际上是由于性能,那么它们如何以及为什么会对性能产生负面影响?使用和语句的问题都源于同一个问题:当使用时,范围界定变得复杂
考虑以下示例:
with (foo) {
with (bar) {
return x;
}
}
这看起来很简单,但实际上可以产生各种可能的结果
如果定义了foo
,并且它有一个名为bar
的属性,bar
有一个名为x
的属性,则返回foo.bar.x
如果未定义foo
,但定义了bar
,并且它有一个名为x
的属性,则返回bar.x
如果定义了foo
,但它没有名为bar
的属性,则使用窗口
查找来检索bar
这个名单还有很多。所以行为有各种各样的可能性,所有这些都是脆弱的,因此可能有bug,但是为什么这是一个性能问题呢
P>嗯,考虑这个:
return foo.bar.x;
没有任何带有
语句的,JavaScript引擎很容易进行优化。范围中是否有一个名为foo
的变量(使用var
声明)?如果是的话,就用这个。如果没有,请执行窗口
查找。这几乎可以静态地确定
将与
一起使用时,需要在运行时动态确定每个单个变量的查找。如果引用的是with
块中的全局变量,则引擎仍必须检查与with
一起使用的对象上是否存在该属性。如果嵌套with
块,情况会变得更糟
将与
一起使用会使行为变得如此复杂,以至于在大多数情况下,JavaScript优化器都会放弃,因为它会抛出大量编译时保证如果范围是动态确定的,而不是词汇确定的,则很难进行推理。
是的,这也是为什么将与
一起使用是个坏主意的另一个原因。不惜一切代价避免它。也许相反,有人在MDN上引用了这本书,但没有署名。我认为你把它复杂化了一点。传递给的对象位于作用域链的顶部,因此首先在对象上解析标识符,然后在作用域链上解析标识符。变量声明变得更有趣了。@RobG是的,当然。关键是我用粗体写的内容。如果不使用和,许多变量引用都可以静态执行,因为一切都是词汇范围的。将与
一起使用,可以有效地为所有可能的变量引用引入动态范围,从而抛弃所有潜在的优化。