PDA

Просмотр полной версии : Создание и хранение объекта


Ariel
26.04.2007, 02:11
Создаю экземпляр ::
var god:God=new God();

И такая запись тоже работает без проблем ::
new God();Объясните разницу. :confused:
Спасибо

iNils
26.04.2007, 02:52
В первом случаи, вы имеет ссылку на созданный экземляр.
Во втором - нет.

etc
26.04.2007, 03:16
Можно считать, что во втором случае ссылка уходит в никуда.

Ariel
26.04.2007, 03:21
Но объект успешно создается (во втором случае) и успешно существует, да?

etc
26.04.2007, 03:22
Да, конечно.

Kikasso
26.04.2007, 03:28
Не понял. Что, серьезно? На объект нет ссылок, почему он не самоудалился? Счас посмотрю. Жив... ну и ну.

etc
26.04.2007, 03:29
А почему он должен удалится? Конструктор выполнится, а дальше он будет удален, если в конструкторе не было создано ссылок на него.

Kikasso
26.04.2007, 04:13
не понимаю, как проверить наличие объекта, не создавая на него ссылок..
Только setInterval совместно с trace - в дебаггере ничего нет, объект остается. Но передаю this аргументом, столо быть ссылка есть.

etc
26.04.2007, 13:20
Верно. Я не говорю, что после выполнения конструктора объект останется. Все зависит от того, создаются ли в конструкторе ссылки на самого себя или нет. Если нет, то созданный объект после отработки будет расплющен и отодран от асфальта мусорником.

Ariel
27.04.2007, 22:43
А в чем будет разница между var god:God=God(); и
var god:God=new God();

iNils
27.04.2007, 22:46
Такой простенький пример.
function God () {
this.q = 5;
}
var god1 = God ();
var god2 = new God ();
trace (god1.q)
trace (god2.q)

Ariel
27.04.2007, 23:20
Э-э .. Не допонял я... Эти два случая иллюстрируют применение синтаксиса АС, насколько я понимаю... Вариант с new - это создание переменной, содержащей сцылку на функцию. Без new - создание переменной, содержащей результат работы функции. Чтоб этот вариант успешно отработал, надо превратить по факту процедуру God в функцию:
function God () {
this.q = 5;
return q;
}

Но с классами-то у нас несколько иная песня.. Я ж не могу получить "результат работы класса".. Или могу? Результат работы конструктора? В таком случае, будет ли успешно создан экземпляр самого класса??

etc
27.04.2007, 23:23
Будет создан экземпляр класса. Конструктор не может ничего возвращать.

iNils
27.04.2007, 23:34
AS2 это надстройка над AS1. Поэтому запись
_global.God = function () {
this.q = 5;
};
идентична записи
class God {
function God () {
this.q = 5;
}
}

Ariel
27.04.2007, 23:35
2 __etc: Не создаётся...
var god:God=God(this);
возвращает null в god. Но если с префиксом new задать, то экземпляр создается успешно... :(

etc
27.04.2007, 23:40
2 __etc: Не создаётся...
var god:God=God(this);
возвращает null в god. Но если с префиксом new задать, то экземляр создается успешно... :(
Данная конструкция для интерпритатора означает кастинг, который и возвращает null, потому что _root не есть God.

Ariel
27.04.2007, 23:42
2 Inils: Да, но вот только вариант с глобалом позволяет вставить return ::
_global.God = function () {
this.q = 5;
return this.q;
};

trace(God());
а в стандартый конструктор внешнего класса его уже не вставишь...

iNils
27.04.2007, 23:43
_root не есть God.:D Истина!

etc
27.04.2007, 23:52
Угу, в прямом и переносном смысле.
В общем new создает экземпляр некоторого объекта, а в роли конструктора выступает та самая описанная функция. Вообще, реализовывать классы на AS1 можно (особенно Ваня долго пытался меня к этому приучить, но не вышло), но сейчас это, имхо, глупо и не нужно.

iNils
27.04.2007, 23:55
Вообще, реализовывать классы на AS1 можноГод назад я этим и занимался. Веселое время было.

etc
27.04.2007, 23:55
Сейчас это совершенно неактуально.

iNils
28.04.2007, 00:00
Сейчас это совершенно неактуально.Ну... Вдруг денег нет на mx 2004, 8 или CS3 (дебильное название, буду ее теперь 9-ой называть). Приходится тогда все на прототипах писать.

Ariel
28.04.2007, 00:08
Так я значит к чему: когда мы пишем с new, а когда без? Delegate нормально создается и работает без new, а мой класс God без new не живет, не пашет...

iNils
28.04.2007, 00:14
Не надо путать метод класса и экземпляра.
Вот у String, метод fromCharCode - это метод класса. Все остальные методы экземпляра. А Math, все методы - методы класса, потому, что не надо создавать экземпляр.

Ariel
28.04.2007, 00:35
Ага... Имеется ввиду определение static function... Т.е., получается, что Math организован просто как библиотека функций.. У него и конструктора-то нет..

etc
28.04.2007, 00:41
Конструктор есть, только не делает ничего. В Math, in fact, хранится куча статических функций и все.

WindWalker
28.04.2007, 01:33
А в чем будет разница между var god:God=God(); и
var god:God=new God();

Если перед функцией стоит оператор new, то создаётся новый объект и функции отдаётся ссылка на него в this.
Ну плюс ещё идёт привязка к прототипу.

Если не писать new, то объект создан не будет, соответственно this будет null. Но функция всё равно выполнится - как любая другая функция.

Данная конструкция для интерпритатора означает кастинг, который и возвращает null, потому что _root не есть God.

Неправда. Данная конструкция означает "Выполни функцию God с одним параметром").
Хоть функция называется с большой буквы и является конструктором, она по-прежнему остаётся функцией.

Например функция Number() используется и как конструктор, и как кастинг.
Вот так это выглядело в 5-м флеше:

function Number (v) {
v = ASnative(3, 1)(v);
if (!ASNew()) {
return (v);
}
this.value = v;
ASSetPropFlags(this, null, 7);
}

То есть с помощью ASNew определялось, каким образом была запущена функция (с оператором new или без) и в зависимости от этого зависело её поведение.

Вот другой пример:
ASNew = ASnative(2, 0);

function God(param) {
if (ASNew()) {
trace ("new");
} else {
trace ("cast");
}
}

God(this);
new God(this);

etc
28.04.2007, 01:41
Причем тут какие-то хаки типа ASnative? Нафига их тут применять? Не лезьте, куда не просят, в плеер.
God(this) — проверка чистой воды на то, что this есть экземпляр God, null тому свидетельство, что им не является, потому что _root не кастится в God. Не надо путать именно приведение типа к данному с проверкой. Number пытается привести переданный аргумент в число. Любой кастомный класс этого не делает и возвращает null, если переданный аргумент не является экземпляром данного класса (без new).
Number, String и т.п. — все простые типы, работают они иначе, чем сложные. Для Array есть исключение — совместимость со старыми версиями плеера, где Array(1,2,3) является функцией, создающей и возвращающей массив из аргументов. Любой кастомный класс в AS2 при написании MyClass(anyParam); (без оператора new) выполнит проверку anyParam на то, является ли anyParam экземпляром MyClass или нет. Если нет, то вернет null. В противном случае вернет anyParam с разъяснением для компилятора, что anyParam есть MyClass и у него есть методыи и свойства MyClass.

WindWalker
28.04.2007, 01:53
В самом AS нет такого понятия как приведение типа.
Преобразование типов с помощью Number() и String() реализовано внутри этих функций.
В кастомных классах обычно не реализуется, потому и получем null.
Сам компилятор воспринимает God(this) именно как вызов функции, которой передаётся в качестве параметра this.


Вот ещё один весёлый примерчик.
Имеем такой класс:
class Test {
var className:String = "Test";
var value:Number;

function Test() { }

function setValue(value) {
this.value = value;
}
}


Затем в фрейме пишем:
x = new Test();
x.setValue(1);
y = new x.setValue(2);

trace (x.value+": "+x.className);
trace (y.value+": "+y.className);

Результат будет такой:
1: Test
2: undefined

Потому что y = new x.setValue(2) создаёт новый объект, записывает ему в поле value значение 2, а вот поле className у него останется неопределенным.

И несмотря на то, что функция setValue у нас может играть роль конструктора, выражение x.setValue(1) не имеет никакого отношения к кастингу.


И вот ещё один пример, окончательно разбивающий теорию о кастинге:
function God(param) {
return "hello";
}

trace (new God(this));
trace (God(this));

etc
28.04.2007, 02:07
Сам компилятор воспринимает God(this) именно как вызов функции, которой передаётся в качестве параметра this.
Неправда. Абсолютная.

Объявление типа:
function God() {

}
не есть аналог:
class God {
public function God() {

}
}
Простой тест, что это не аналоги:

function God(param) {
trace('aaa')
}
trace(God(this)); // aaa — сначала вызов
// undefined — трейс результат
А теперь класс God:
import God;
trace(God(this)); // null
Сам класс:
class God {
public function God() {
trace('aaa');
}
}
Будь класс действительно функцией, был бы возврат аналогичный первому вариант, но никак не null, который и означает, что был произведен кастинг this и получен результат. Я уж не говорю про то, что вызова конструктора класса не было, как можно было заметить.

WindWalker
28.04.2007, 02:27
Ладно сдаюсь.
Век живи - век учить. Не знал про такую фичу AS2.0 и всегда считал, что класс = функция.

etc
28.04.2007, 02:29
Ничего страшного. Кастинг — полезная штука. Она дает понять компилятору, с чем он имеет дело. Правда, нужно не забывать делать проверку на null в местах, где это действительно нужно (когда точно не знаешь, что именно может прийти).

Хотя есть некоторые классы, где уже не кастинг, а уже конкретное преобразование типов происходит, например тот же Number, String. Array вернет массив из элементов (сам спотыкнулся (http://dev.etcs.ru/blog/as2/eventdispatcher_assetpropflags_and_casting/)). В AS3 тоже есть моменты, где, например, XML(param) и param as XML не есть одно и то же (XML(loader.data) вернет XML, а loader.data as XML вернет null, loader — URLLoader).