Я видел код JavaScript, который начинается with
. Это немного сбивает с толку. Что это делает и как это может использоваться правильно?
with (sObj) return options[selectedIndex].value;
Он добавляет к объему операторов, содержащихся в блоке:
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 на самом деле довольно хорошо объясняет вещи более подробно (вместе с плюсами и минусами ее использования):
Его эквивалент
return sObj.options[selectedIndex].value;
With
позволяет вам выдавать блок операторов в контексте определенного объекта. Поэтому все операторы в блоке with
считаются членами объекта в скобках.
Это может сделать код более читабельным, но это также может привести к двусмысленности, поскольку ссылки на переменные могут быть либо с sObj, либо глобальными.
В этом блоке вам не нужно вводить:
sObj.options[selectedIndex].value
, но вы можете просто использовать:
options[selectedIndex].value
Это не функция (как было указано в заголовке вопроса до его редактирования), а утверждение. Это может иметь больше смысла, если образец кода отформатирован следующим образом:
with (sObj){
return options[selectedIndex].value;
}
Относительно того, что он делает ( Источник )
Оператор with устанавливает объект по умолчанию для набора операторов. JavaScript ищет любые неквалифицированные имена в наборе операторов, чтобы определить, являются ли имена свойствами объекта по умолчанию. Если неквалифицированное имя соответствует свойству, тогда это свойство используется в операторе; в противном случае используется локальная или глобальная переменная.
Это означает, что в примере кода сначала проверяется, является ли options
свойством sObj
. Если это, то options
относится к sObj.options
, в противном случае он проверяет другие области для переменной, определенной именем options
Обратная сторона использования с оператором
заключается в том, что невозможно узнать, просто взглянув на код, к чему осуществляется доступ. Есть и другие лучшие альтернативы, как показано в этой статье
оператор with
- это чистый синтаксический сахар, но он также может вызвать некоторые неприятные ошибки.
См. with Statement Considered Harmful для разъяснения:
Если вы не можете прочитать программу и быть уверенным, что знаете, что она собирается делать, вы не можете быть уверены, что она будет работать правильно. По этой причине следует избегать утверждения
with
.
Ваш пример можно переписать как...
return sObj.options[selectedIndex].value;
... поскольку оператор 'with' помещает все связанные с ним утверждения в область видимости предоставленного объекта. В данном случае это довольно бессмысленно, но если бы вы выполняли много операций над 'sObj', то это сэкономило бы много текста.
Полностью вымышленный пример...
with (sObj)
{
if(options[selectedIndex].value < 10){
options[selectedIndex].value++;
total+ = options[selectedIndex].value;
}
}
Но, сказав это, часто бывает, что экономия ввода может быть достигнута лучшими способами.
Я бы рекомендовал НЕ использовать это из-за проблем с производительностью, но приведенное выше означает следующее:
для объекта sObj ( здесь предположительно элемент select), все дочерние элементы и свойства, упомянутые в этом элементе (или между следующими фигурными скобками), рассматривают его как свою родительскую область.