Опубликован: 23.12.2005 | Уровень: специалист | Доступ: платный | ВУЗ: Московский физико-технический институт
Лекция 3:

Клипы и ролики. Специальные возможности языка

Инструкция with и обсуждение областей видимости

Программистам часто приходится работать с многократно вложенными объектами (да еще, бывает, с длинными именами). Необходимость постоянно писать что-то наподобие

mySmartObject.favoriteField.theBestMethod(justTheSameArgument)

может изрядно раздражать. А поскольку мы уже умеем создавать вложенные клипы (читай - вложенные объекты), то пора бы познакомиться со способом сократить подобные записи. Способ этот - использование инструкции with .

Простейший пример

Инструкция with имеет синтаксис, похожий на синтаксис инструкции if. То есть сначала следует ключевое слово with , после него в круглых скобках - ссылка на объект, с полями которого мы собираемся работать; после закрывающей круглой скобки начинается блок (обрамленный фигурными скобками), внутри которого идентификаторы в первую очередь интерпретируются как имена полей заданного объекта. Вот простейший пример использования этой инструкции.

x = 100;
trace("x = " + x);
obj = {x: 10, y:15};
with (obj){
   trace("with (obj): x = " + x);
   trace("with (obj): y = " + y);
}
trace("x = " + x);

На выходе получаем:

x = 100
with (obj): x = 10
with (obj): y = 15
x = 100

Пример посложнее

А теперь давайте рассмотрим более сложный пример.

a = {x: 10, y:15};
a.method = function(arg){
   with(this){
      trace("with(this): x = " + x);
      trace("with(this): eval(arg) = " + eval(arg));
   }
   trace("eval(arg) = " + eval(arg));
}
a.method("y");

Здесь инструкция with используется для того, чтобы избавиться от необходимости каждый раз писать this внутри метода некоторого объекта для обращения к его полям. Мы уже говорили об этой неприятной особенности языка ActionScript и о том, что чуть ли не половина ошибок при написании функций-методов происходит из-за того, что программисты написать this все-таки забывают (и какого-либо предупреждения от ActionScript 1.0 при компиляции не дождешься). Так вот, написав with (this) и обрамив относящимися к этой инструкции фигурными скобками все тело функции, вы избавитесь от подобных проблем. Не забудьте только, что для создания новых полей объекта with непригоден (подробнее об этом - чуть дальше).

Кроме того, из этого примера мы увидим, что использование eval замечательно сочетается с with : внутри with (this) надпись типа eval ("x") приведет к правильному результату (выдаче поля х ), а снаружи - нет. В самом деле, после запуска вышеприведенного кода на выполнение, получим в консоли следующий результат:

with(this): x = 10
with(this): eval(arg) = 15
eval(arg) =

Многоуровневые with

У инструкции with есть удобное свойство: внутри блока, относящегося к with , можно использовать еще одну инструкцию with . Вот пример работы с вложенными with :

a = {x: 10, y:15};
b = {x: 100, y: 150};
a.method = function(arg){
   with(this){
      trace("with(this): x = " + x);
      trace("with(this): eval(arg) = " + eval(arg));
      with (b){
         trace("with(b): x = " + x);
         trace("with(b): eval(arg) = " + eval(arg));
      }
      this.b = {x: 1000, y: 1500};
         // В качестве объекта, с которым работает следующий
         // оператор with будет взят объект this.b, потому что
         // мы находимся внутри блока, принадлежащего with(this)
      with (b){
         trace("with(b): x = " + x);
         trace("with(b): eval(arg) = " + eval(arg));
      }
      trace("with(this): x = " + x);
      trace("with(this): eval(arg) = " + eval(arg));
   }
   trace("eval(arg) = " + eval(arg));
}

a.method("y");

Выводит этот код вот что:

with(this): x = 10
with(this): eval(arg) = 15
with(b): x = 100
with(b): eval(arg) = 150
with(b): x = 1000
with(b): eval(arg) = 1500
with(this): x = 10
with(this): eval(arg) = 15
eval(arg) =

Интересно, что как только мы создали объект this.b, именно он стал в первую очередь восприниматься в качестве b (до тех пор, пока мы находились внутри блока with (this) ). В следующем параграфе мы обсудим вопрос старшинства областей видимости более детально.

Зарина Каримова
Зарина Каримова
Казахстан, Алматы, Гимназия им. Ахмета Байтурсынова №139, 2008
Akiyev Begench
Akiyev Begench
Беларусь, Полоцк, полоцкий государственный университет