陈述的表现影响

时间:2015-02-21 23:22:03

标签: javascript with-statement

好的,所以,在过去的四十八小时里,我已经看到了这一点,我需要提出这个问题。在" JavaScript for Professional Web Developers" (2012)它与MDN上的内容相同:

  

建议不要使用with语句,因为它可能是来源   令人困惑的错误和兼容性问题。

然而,Zakas'本书还指出(没有进一步的实质性阐述),出于性能原因,#34; [它们不应被使用]"。这个问题显然已经足够严重了#34;在Strict模式下,ECMAScript不允许with语句。

这是出于性能原因吗?或者,是因为人们无法忍受它们吗?

如果部分原因在于表现,那么它们如何以及为何对性能产生负面影响?

1 个答案:

答案 0 :(得分:7)

with语句的问题都源于同一个问题:使用with时,范围变得复杂

考虑以下示例:

with (foo) {
    with (bar) {
        return x;
    }
}

这看似简单,但它实际上可以产生各种可能的结果。

  1. 如果foo定义为,则它具有名为bar 的属性,而 bar具有名为{{1}的属性},然后返回x
  2. 如果foo.bar.x未定义,但foo是,并且它有一个名为bar的属性,则会返回x
  3. 如果定义bar.x但没有名为foo的属性,则使用bar查找检索bar
  4. 列表还在继续。所以行为有各种各样的可能性,所有这些都是脆弱的,因此可能存在错误,但为什么这是性能问题呢?

    好吧,考虑一下:

    window

    没有任何return foo.bar.x; 语句,JavaScript引擎很容易进行优化。范围内是名为with的变量(使用foo声明)?如果是这样,请使用它。如果没有,请执行var查找。这几乎可以静态地确定。

    使用window时,每个变量查找都需要在运行时动态确定。如果您在with块内引用全局变量,则引擎仍然必须检查与with一起使用的对象上是否存在该属性。如果with块嵌套,则会变得更糟。

    使用with会使行为变得如此复杂,以至于在大多数情况下,JavaScript优化器只会放弃,因为它会抛出大量的编译时保证。 当范围是动态确定的,而不是词汇,很难推理。

    所以是的,这是使用with是个坏主意的另一个原因。不惜一切代价避免它。