Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Psycho Tiger

Оценить эту запись

Этот классный this.

Запись от Psycho Tiger размещена 13.12.2010 в 00:38

Каждый флешер просто обязан знать что такое this. this — ссылка на "себя", на текущую область видимости можно сказать.
Чаще всего this будет ссылкой на экземпляр класса, в котором выполняется этот код. Его использование перед другими операторами, например такими как точка (.) позволяют уточнить область видимости, где нужно найти переменную. Это бывает очень полезно если вдруг случилось так, что локальная переменная и поле класса имеют одинаковые идентификаторы. Мне, кстати, всегда было немного забавно как новички налево и направо лепят this, а когда встречают строчку с super очень пугаются. Но мы совсем не о том.
Давайте подумаем, что мы можем получить в качестве this.
Очевидно, что текущий экземпляр, в случае если this написано в методе или конструкторе. Создав функцию мы можем поменять ей this с помощью методов apply и call класса Function. Если функция вызывается сразу же, с помощью оператора скобок ( ) — тогда контекст this будет такой же, как и в методах, другими словами ссылкой на текущий экземпляр.
this, как и super кстати говоря нельзя использовать вместе с модификатором static. Оно и понятно — какое может быть this если у нас нет экземпляров. Хотя, чисто по логике this в таком случае может ссылаться на Class в котором он написан, но этого не происходит. И слава богу, программист сам в состоянии знать в каком классе он пишет код и скорее всего написав this он допустил ошибку.
Теперь давайте побудем крутыми. Получим ссылку на Class через this, утрём нос этим конформистам.
Код AS3:
package
{
	import flash.display.Sprite;
 
	public class SomeBaseClass extends Sprite
	{
		public function SomeBaseClass() {
			super();
			var func:Function = function():void { trace(this); };
			func.apply(SomeBaseClass); //[class SomeBaseClass]
		}
	}
 
}
На самом деле так может каждый, в этом нет ничего зазорного, помимо того что следует плюнуть в лицо тому, кто такое напишет.
Но многие ли из вас способны заставить this ссылаться на Class... не используя ни apply, ни call, ни создавая функций? Я вот тоже не могу.
Но на этой почве можно поссорить интерпретатор с компилятором )
Например, напишите вот такой код:
Код AS3:
package
{
	import flash.display.Sprite;
 
	public class SomeBaseClass extends Sprite
	{
		private var someThing:NewClass = new NewClass(this);
		public function SomeBaseClass() {
			super();
		}
	}
 
}
Код AS3:
package {
	public class NewClass {
		public function NewClass(someArg:SomeBaseClass):void {
			trace(someArg);
		}
	}
}
К нашему общему удивлению код не скомпилируется и компилятор услужливо скажет нам:
Код:
***\src\SomeBaseClass.as(7): col: 49 Error: Implicit coercion of a value of type Class to an unrelated type SomeBaseClass.
Причем скажет это два раза. "Эээ..." — задумчиво сказал я. Компилятору, наверное, виднее. Ловко меняем someArg:SomeBaseClass на Class и... оно компилируется. Но не долго длится счастье, сразу же ловим RTE, где нам услужливо объясняют что, дескать, товарищ компилятор не прав и передали вовсе не Class, а вполне себе экземпляр объекта.
Теперь на этом моменте можно остановится и помечтать. Что же это значить может? Почему инициализируя поле в том блоке кода компилятор считает что там Class? Кто знает, может это и есть поддержка this в static, которую потом выпилили, а это осталось. Кто знает, может это знак что мне стоит прекратить работать до 4 утра по воскресеньям. Кто знает...
Всего комментариев 11

Комментарии

Старый 13.12.2010 02:29 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Если перенести создание NewClass в конструктор, никаких ошибок не возникает.
Как я понял, this (SomeBaseClass) еще не существует в момент создания NewClass. И было бы неправильно, чтобы такая конструкция компилировалась.
Странно то, что если поменять тип на Class, то оно компилится =)
Старый 13.12.2010 12:14 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Аха, верно.
На самом деле банальный глупый баг. Но почему то захотелось поделиться =)

Кстати про this "не существует" не правильно. Баг наблюдается только если передавать его в новый создаваемый объект. Если банально сохранить ссылку на this в поле класса - всё происходит верно.
Старый 15.12.2010 15:01 etc вне форума
etc
 
Аватар для etc
На самом деле, это даже не баг толком, код вне методов и конструкторов тоже имеет область видимости, где this как раз и есть Class, но не текущий класс (т. к. блок ещё выполняется). Экземпляр же передается в силу того, что значение поля объявляется на самом деле в начале конструктора.

Мне вот больше не нравится то, что я не могу в конструкторе написать var something:int = super.getSomething();
Старый 15.12.2010 16:03 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Цитата:
На самом деле, это даже не баг толком, код вне методов и конструкторов тоже имеет область видимости, где this как раз и есть Class, но не текущий класс (т. к. блок ещё выполняется). Экземпляр же передается в силу того, что значение поля объявляется на самом деле в начале конструктора.
Хорошо, но если сохранить ссылку на this в каком нибудь поле класса, то это поле класса будет указывать на экземпляр. Разницы в байткоде межу объявлением в поле класса непосредственно и в конструкторе я не заметил (смотрел давно ещё), тамаринка при всех тестах говорила что передан экземпляр объекта. Имо это баг компилятора, сродни super.x+=
Цитата:
Мне вот больше не нравится то, что я не могу в конструкторе написать var something:int = super.getSomething();
Речь идёт о написании super. до super() ? Тоже в своё время удивляло. Я ведь могу написать getSomething. Но super.getSomething - низя)
Старый 15.12.2010 19:16 etc вне форума
etc
 
Аватар для etc
Не до, а пофиг где, можно и после. Но только для объявленных локальных переменных.
Старый 15.12.2010 20:10 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Ох ты, вот оно в чем дело. Спасибо, а я иногда понять не мог, что не так)
Старый 16.12.2010 00:55 etc вне форума
etc
 
Аватар для etc
А все потому что сами переменные объявляются до super(). А значение после. В итоге компилятор косячит, непонятно как считая объявление переменной в коде.
Старый 16.12.2010 13:39 Psycho Tiger вне форума
Psycho Tiger
 
Аватар для Psycho Tiger
Цитата:
А все потому что сами переменные объявляются до super(). А значение после. В итоге компилятор косячит, непонятно как считая объявление переменной в коде.
Интересная теория)
Старый 06.02.2011 17:02 tsarapkabel вне форума
tsarapkabel
 
Аватар для tsarapkabel
Частенько в постах Psycho Tiger я замечаю конструкцию вида

Код AS3:
public class SomeBaseClass extends Sprite {
 
	public function SomeBaseClass() {
		super();
	}
}
И никак не могу понять, для чего тут этот super()?
В моём понимании — это явный вызов метода конструктора Sprite. Для чего, что это даёт? А если это вызов, то что в конструкторе Sprite?
Старый 06.02.2011 17:25 derhab вне форума
derhab
 
Аватар для derhab
Старый 06.02.2011 18:03 tsarapkabel вне форума
tsarapkabel
 
Аватар для tsarapkabel
Точно! Вчера уже без меня обсудили Извиняюсь, не видел.

Итог:
Цитата:
Сообщение от mikhailk Посмотреть сообщение
Без супера не обойтись, если необходимо вызвать конструктор супер класса с параметрами. Без параметров есть он или нет ни на что не влияет.
Цитата:
Сообщение от Psycho Tiger Посмотреть сообщение
Гораздо проще увидеть super() в самом верху и успокоится, что здесь всё стандартно. В противном случае нет той подсказки, которая сообщит мне, где же будет super. Мне придется пользоваться поиском.
 

 


Часовой пояс GMT +4, время: 10:31.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.