Что не так с оператором WITH в JavaScript? - PullRequest
2 голосов
/ 22 мая 2009

Кажется, я помню, что есть проблема с WITH. Я не скучаю по этому; Я предпочитаю, чтобы каждая строка моего кода стояла сама по себе.

Я начал задумываться об этом, когда узнал (в SO), что люди считают цепочку одной из своих любимых функций jQuery. JavaScript и WITH в JQuery, по сути, являются одной и той же функцией, верно?

Ответы [ 7 ]

8 голосов
/ 22 мая 2009

Нет, они не одно и то же ...

С является сокращением для ссылки на членов класса без необходимости полностью уточнять их имена.

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

Прочтите, что Дуглас Крокфорд говорит о С. Он призывает избегать этого - говорит, что он подвержен ошибкам и неоднозначен. Я согласен с ним.

jQuery-цепочка - это способ реализовать гибкий интерфейс, который позволяет передавать результаты одного метода напрямую в другой. То есть вывод данного метода служит входом в следующий. JQuery цепочка может действительно выглядеть, если вы используете много пробелов. Пример ниже от Джона Ресига показывает это.

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

Читайте о jQuery цепочках здесь и здесь

6 голосов
/ 22 мая 2009

С и цепочка не совсем то же самое. С влияет на область, а цепочка - нет. Рассмотрим:

a.b.c = foo;

или

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

Во втором случае вы понятия не имеете, существует ли c вне блока with, поэтому, если возможно, что вы просто забиваете что-то, на что полагается другая часть программы.

4 голосов
/ 22 мая 2009

Кстати, я категорически не согласен с Крокфордом и всем анти-с движением. Да, мне тоже нравится порка умерших наездников.

Я согласен с анти-аргументом в том, что с никогда не следует использовать его в качестве опоры для создания / назначения объекта, что фактически означает, что он никогда не использовался напрямую:

BAD

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

GOOD

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

Я полагаю, что вторая форма на самом деле повышает удобочитаемость, поскольку она одновременно указывает на блок (с самим собой) и удаляет пробелы (меньше текста = меньше мозговых болей) без обращения к избыточным объявлениям / назначениям. Я утверждаю, что с опасно только тогда, когда вы не знаете, что делаете, и я продолжаю: если вы не знаете, что делаете, вы не должны этого делать. Как я уже сказал, я понимаю, что я против зерна здесь.

2 голосов
/ 22 мая 2009

Вы должны прочитать с утверждением «Считается вредным» для хорошего объяснения того, почему вам следует избегать with.

Нет, with - это не то же самое, что цепочка:

Оператор JavaScript with был предназначен для того, чтобы обеспечить сокращение для записи повторяющихся обращений к объектам.

1 голос
/ 22 мая 2009

Я думаю, что вопрос был дан ответ выше, просто хотел добавить два моих цента на тему «с». Пример, который привел почти каждый из вас, - это неоднозначные имена классов и переменных, которые с с или без с трудно поддерживать и понимать. Если вы называете свои переменные, классы, объекты с каким-то значением с могут быть золотыми.

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 , в блоке с только ax get переопределяется, поскольку это текущая область.

0 голосов
/ 07 июня 2011

Вы можете использовать с оператором для следующей операции

a.b.c.d.e.foo = SomeValue; a.b.c.d.e.doo = somevar;

в

с (a.b.c.d.e) { Foo = SomeValue; ду = somevar; }

но у вас есть хороший вариант в javascript

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

Это сделает процедуру простой:)

0 голосов
/ 22 мая 2009

Или вы можете ссылаться на Mozilla здесь получить дополнительную информацию.

Ниже приведен фрагмент статьи

'with' затрудняет для читателя или компилятора JavaScript решение о том, будет ли найдено неквалифицированное имя в цепочке областей действия, и если да, то в каком объекте. Итак, учитывая этот пример:

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

только когда вызывается f, x либо найден, либо нет, а если найден, либо в o, либо (если такого свойства не существует) в объекте активации f, где x называет первый формальный аргумент. Если вы забудете определить x в объекте, который вы передаете в качестве второго аргумента, или если есть какая-то похожая ошибка или путаница, вы не получите ошибку - только неожиданные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...