JavaScript中的“with”关键字有什么作用?

20

我看到了一些以 with 开头的 JavaScript 代码。这有点令人困惑。它是做什么的,如何正确使用?

with (sObj) return options[selectedIndex].value;
8个回答

22

它扩展了包含在块中的语句的范围:

return sObj.options[selectedIndex].value;

可以变成:

with (sObj)
    return options[selectedIndex].value;

在您的情况下,它并没有做太多事情... 但考虑以下情况:

var a, x, y;
var r = 10;
a = Math.PI * r * r;
x = r * Math.cos(PI);
y = r * Math.sin(PI /2);

变成:

var a, x, y;
var r = 10;
with (Math) {
  a = PI * r * r;
  x = r * cos(PI);
  y = r * sin(PI / 2);
}

...省去了几次按键。Mozilla文档实际上很好地解释了更多细节(以及使用它的优缺点):

with - Mozilla开发者中心


使用不方便,就像在VBA中一样。在Python中,我们可以处理一次性对象的清理工作。在C#中,它被称为using。 - Hamish Grubijan
@Mark - 谢谢。看起来我应该包括“建议不要使用此”条款。 - Justin Niessner
+1 感谢Justin回答问题。仅仅说“不要使用它”很容易,但如果我们努力去理解和尝试功能,我们就可以做出明智的决定。 - plodder

11
with 语句是一种纯粹的语法糖,但它也可能导致一些严重的错误。请参阅with 语句是有害的以获得更多解释:
“如果您无法阅读程序并确信自己知道它将要做什么,那么您就无法确信它将正确工作。因此,应避免使用 with 语句。”

2
++ 用于提及 'with' 的缺点 - Gordon Gustafson

2
在那个 with 块中,您不必键入:
在该代码块中,您无需输入:
sObj.options[selectedIndex].value

但你可以直接使用:

options[selectedIndex].value

2
这是“等同于”的意思。
return sObj.options[selectedIndex].value;

`with`语句允许在特定对象的上下文中执行一块语句。因此,`with` 块中的所有语句都被视为括号内对象的成员。
这有时可以使代码更易读,但也可能会导致歧义,因为变量引用可能使用 `sObj` 或全局变量。 JavaScript "with"语句的合法用途 :D

1

这不是一个函数(在编辑之前的问题标题中指出),而是一个语句。如果代码示例格式化如下,则可能更有意义:

with (sObj){
    return options[selectedIndex].value;
}

关于它的作用(源代码

with语句为一组语句建立默认对象。JavaScript在一组语句中查找任何未限定的名称,以确定这些名称是否是默认对象的属性。如果未限定的名称与属性匹配,则该属性用于语句;否则,使用本地或全局变量。

这意味着在代码示例中,首先检查options是否是sObj的属性。如果是,则options指的是sObj.options,否则它会检查其他范围内是否有以options命名的变量。

使用with语句的缺点是仅凭一眼扫过代码就无法知道访问了哪些内容。如本文所示,还有其他更好的替代方案。


虽然你的回答其他部分是正确的,但格式相对来说并不重要。 - belugabob
@belugabob 请阅读答案,而不是猜测其内容。我从未提到格式化与with语句有任何关系。我说如果使用大括号进行格式化,它会更有意义,因为这使它看起来不像函数调用,而更像一个语句。 - Yacoby
@belugabob 我也重新排列了单词顺序,以避免产生误解。 - Yacoby
是的 - 现在更有意义了。 - belugabob

1

你的例子可以重写为...

return sObj.options[selectedIndex].value;

...由于'with'语句将所有相关语句放置在提供的对象范围内,因此可以省略一些代码。在这种情况下,这是相当无意义的,但是如果您要对'sObj'执行大量操作,则可以节省很多打字。

完全虚构的例子...

with (sObj) 
{
   if(options[selectedIndex].value < 10){
       options[selectedIndex].value++;
       total+ = options[selectedIndex].value;
   }
}

不过话说回来,通常可以更好地实现节省输入。


1
我建议出于性能问题不要使用这个,但以上的意思是:
对于对象 sObj (这里可能是一个 select 元素),所有子元素和在此元素上引用的属性(或花括号之间的属性)都将把它作为它们的父级作用域。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接