JavaScript中的WITH语句有什么问题?

时间:2009-05-22 13:59:41

标签: javascript jquery

我似乎记得WITH有问题。我不会错过它;我更喜欢我的代码的每一行都独立存在。

当我学习(在SO)人们考虑链接他们最喜欢的jQuery功能时,我开始想知道这一点。 JavaScript的WITH和jQuery的链接基本上是相同的功能,对吧?

7 个答案:

答案 0 :(得分:8)

不,他们不是一回事......

使用是引用类成员的简写,无需完全限定其名称。

with o 
{
   x = y;   // where x is a member of o. But how can you tell for sure?
}

阅读道格拉斯·克罗克福德关于With的内容。他鼓励避免它 - 说它容易出错并且含糊不清。我同意他的意见。

jQuery链接是一种实现流畅接口的方法,允许您将结果从一个方法直接传递到另一个方法。也就是说,给定方法的输出作为下一个方法的输入。如果你使用大量的空格,jQuery链接确实可以看起来像。以下示例来自John Resig的演示。

jQuery("div").hide("slow", function(){
  jQuery(this)
    .addClass("done")
    .find("span")
      .addClass("done")
    .end()
    .show("slow", function(){
      jQuery(this).removeClass("done");
    });
});

Read about jQuery chaining herehere

答案 1 :(得分:6)

与链接并不完全相同。有影响范围,而链接没有。考虑:

a.b.c = foo;

或:

with(a.b) { c = foo; }

在第二种情况下,你不知道c是否存在于with块之外,所以如果你可能只是在破坏程序的另一部分依赖的东西。

答案 2 :(得分:4)

fwiw,我强烈不同意crockford和整个反运动。是的,我也喜欢鞭打已故的马术运动员。

我同意反对的观点是,永远不应该用作对象创建/赋值的拐杖,这实际上意味着从未直接使用过:

BAD

with(a.b)
{
  c = x;
}

GOOD

with(a)
{
  b.c = x;
}

我相信第二种形式实际上增加了可读性,因为它既指示了一个块(带有它自己)又删除了空格(少了文本=少了脑筋)而没有求助于冗余的声明/赋值。我的论点是,只有当你不知道自己在做什么时,这只会是危险的,而我的后续行动是,如果你不知道自己在做什么,就不应该这样做。正如我所说,我意识到我在这里反对。

答案 3 :(得分:2)

您应该阅读with Statement Considered Harmful,以获得有关您应该避免with的原因的详细说明。

不,with与链接不一样:

  

JavaScript的with语句旨在提供写入对象的重复访问的简写。

答案 4 :(得分:1)

我认为上面已经回答了这个问题,只是想在'with'这个主题上加上我的两分钱。几乎所有人提出的例子都是暧昧的类和变量名, with with 很难维护和理解。如果您为变量命名,那么具有某种含义 with 的类,对象可能是黄金。

var car = {
           wheels: {radius: 5, rim: 'gold', shape: 'circle'},
           body: {color: 'black', windows: 'tinted'}
           };

和现在:

with (car){
    wheels.shape = square;
    body.color = blue;
}

重点是,功能强大,为您后程序员节省了大量时间。只有正确使用它并且已经习惯了变量的详细命名和充分的注释,它才能正常工作。此外,有人说,如果你这样做:

with(a){
    x = 3;
}

以某种方式,某个不是该类成员的变量将以某种方式被覆盖。如果我错了,请纠正我,但如果 x 和属性 ax ,则 块中只有由于这是当前的范围,因此得到了覆盖。

答案 5 :(得分:0)

或者您可以参考Mozilla here获取更多信息。

以下是文章的一部分

'with'使得人类读者或JavaScript编译器很难决定是否在范围链中找到非限定名称,如果是,则在哪个对象中找到。所以给出这个例子:

  function f(x, o) {
    with (o)
      print(x);
  }

仅当调用f时才发现x,如果找到,则在f的激活对象中以o或(如果没有这样的属性),其中x命名第一个正式参数。如果您忘记在作为第二个参数传递的对象中定义x,或者如果存在类似的错误或混淆,则不会出现错误 - 只是意外结果。

答案 6 :(得分:0)

您可以使用with语句进行以下操作

a.b.c.d.e.foo = someValue中; a.b.c.d.e.doo = somevar;

作为

与(a.b.c.d.e) {      富= someValue中;      斗= somevar; }

但你在javascript中有很好的选择

var v = a.b.c.d.e; v.foo = someValue中; v.doo = somevar;

这将使程序变得简单:)