Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 语句对性能的影响_Javascript_With Statement - Fatal编程技术网

Javascript 语句对性能的影响

Javascript 语句对性能的影响,javascript,with-statement,Javascript,With Statement,好的,在过去的48个小时里,我已经看到了足够多的人提到过这一点,我需要把它作为一个问题来问。在“”(2012)中,它所说的与它在上所说的一样: 不建议使用with语句,因为它可能是源代码 容易混淆的bug和兼容性问题 然而,Zakas的书也指出(没有进一步的实质性阐述),“出于性能原因,[不应该]使用它们”。这个问题显然“非常糟糕”,在Strict模式下,ECMAScript不允许使用语句 这真的是出于性能原因吗?或者,是因为人们无法忍受他们 如果部分原因实际上是由于性能,那么它们如何以及为什么

好的,在过去的48个小时里,我已经看到了足够多的人提到过这一点,我需要把它作为一个问题来问。在“”(2012)中,它所说的与它在上所说的一样:

不建议使用with语句,因为它可能是源代码 容易混淆的bug和兼容性问题

然而,Zakas的书也指出(没有进一步的实质性阐述),“出于性能原因,[不应该]使用它们”。这个问题显然“非常糟糕”,在
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是的,当然。关键是我用粗体写的内容。如果不使用
    ,许多变量引用都可以静态执行,因为一切都是词汇范围的。将
    一起使用,可以有效地为所有可能的变量引用引入动态范围,从而抛弃所有潜在的优化。