好的,所以,在过去的四十八小时里,我已经看到了这一点,我需要提出这个问题。在" JavaScript for Professional Web Developers" (2012)它与MDN上的内容相同:
建议不要使用with语句,因为它可能是来源 令人困惑的错误和兼容性问题。
然而,Zakas'本书还指出(没有进一步的实质性阐述),出于性能原因,#34; [它们不应被使用]"。这个问题显然已经足够严重了#34;在Strict
模式下,ECMAScript不允许with
语句。
这是出于性能原因吗?或者,是因为人们无法忍受它们吗?
如果部分原因在于表现,那么它们如何以及为何对性能产生负面影响?
答案 0 :(得分:7)
with
语句的问题都源于同一个问题:使用with
时,范围变得复杂。
考虑以下示例:
with (foo) {
with (bar) {
return x;
}
}
这看似简单,但它实际上可以产生各种可能的结果。
foo
定义为且,则它具有名为bar
的属性,而 bar
具有名为{{1}的属性},然后返回x
。foo.bar.x
未定义,但foo
是,并且它有一个名为bar
的属性,则会返回x
。bar.x
但没有名为foo
的属性,则使用bar
查找检索bar
。列表还在继续。所以行为有各种各样的可能性,所有这些都是脆弱的,因此可能存在错误,但为什么这是性能问题呢?
好吧,考虑一下:
window
没有任何return foo.bar.x;
语句,JavaScript引擎很容易进行优化。范围内是名为with
的变量(使用foo
声明)?如果是这样,请使用它。如果没有,请执行var
查找。这几乎可以静态地确定。
使用window
时,每个变量查找都需要在运行时动态确定。如果您在with
块内引用全局变量,则引擎仍然必须检查与with
一起使用的对象上是否存在该属性。如果with
块嵌套,则会变得更糟。
使用with
会使行为变得如此复杂,以至于在大多数情况下,JavaScript优化器只会放弃,因为它会抛出大量的编译时保证。 当范围是动态确定的,而不是词汇,很难推理。
所以是的,这是使用with
是个坏主意的另一个原因。不惜一切代价避免它。