Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Как объекту убить самого себя? (http://www.flasher.ru/forum/showthread.php?t=111679)

chingachgoog 05.05.2008 13:09

Как объекту убить самого себя?
 
собственно вопрос

etc 05.05.2008 13:20

Никак.

chingachgoog 05.05.2008 13:45

Хм.
Но если очень хочется, а нельзя, то вроде можно:

Код:

zz={}
zz.test="qwerty"

trace(zz.test)
trace(zz)

zz.del=function(){
        this.death=true
        for (var i in _root) {
                if (_root[i].death){
                        delete _root[i]
                }
        }
}

zz.del()



trace(zz.test)
trace(zz)


etc 05.05.2008 16:30

Ну вы же понимаете, что это, мягко говоря, не есть решение?

chingachgoog 05.05.2008 18:08

Ничего лучшего пока не придумал, но хоть так работает. :)

Жень Шень 05.05.2008 18:29

Цитата:

Сообщение от chingachgoog (Сообщение 737253)
Хм.
Но если очень хочется, а нельзя, то вроде можно:

Так проще:
Код:

zz = {};
zz.kill = kill
zz.test = "qwerty";
trace(zz.test);
trace(zz);
zz.kill();
trace(zz.test);
trace(zz);
//
function kill() {
 zz={}
 delete zz
}


Molecula 05.05.2008 18:34

У Object-a нет команды самоликвидации.
Вы просто удаляйте всё по мере необходимости и всё:
Код:

var s:Sound = new Sound();
trace(s)
delete s;
trace(s);

Можно расширить класс, добавив св-ва и методы, а после уже наследоваться от него.

Жень Шень 05.05.2008 19:20

Вопрос был "Как объекту убить самого себя?"
Я в примере как раз и добавил метод "самоликвидации".
Правда в функции лишняя строчка, надо так:
Код:

function kill() {
 delete zz
}


Molecula 05.05.2008 19:41

Жень Шень, а смысл создавать лишнее?
Если просто вызвать ф-цию:
Код:

kill();
Вместо строки:
Код:

zz.kill();
Эффект один и тот же.
Соответственно вот это:
Код:

zz.kill = kill
само собой отпадает.

Получится:
Код:

zz = {};
zz.test = "qwerty";
kill();
function kill() {
 delete zz
}

То же, что и я написал на верху.

Что бы объект убил себя, нужно что-то типа такого:
Код:

var o:Object = new Object();
o.onPress = kill;
function kill(){
this.destroyItSelf();
trace(o)// undefined;
}


iNils 05.05.2008 19:43

Жень Шень, есть одна проблема, в функции явно указывается имя объекта, поэтому применить его к любый объектам не получится.
Поэтому, лучше сразу задавать имя объекту
Код:

function Obj (parent, name) {
        this.parent = parent;
        this.name = name;
        this.test = "qwerty";
}
Obj.prototype.del = function () {
        delete this.parent[this.name];
};
var obj1 = new Obj (this, "obj1");
var obj2 = new Obj (this, "obj2");
_global.obj3 = obj1;
trace (obj1 + " " + obj1.test);
trace (obj2 + " " + obj2.test);
obj1.del ();
trace (obj1 + " " + obj1.test);
trace (obj2 + " " + obj2.test);
obj2.del ();
trace (obj1 + " " + obj1.test);
trace (obj2 + " " + obj2.test);


chingachgoog 05.05.2008 20:01

Как правильно сказал iNils, есть проблема - в функции не должно быть явно указано имя объекта. Поэтому код типа
Цитата:

delete zz
не подходит :) Честно говоря не ожидал что его предложат :)

Но и создавать объект, дополнительно задавая ему (по сути вручную) параметром его же имя - тоже неверно. Если разобраться, то iNils выполнил тот же код:
Цитата:

delete zz
только более извращенно. :)

в моем коде, типа
Цитата:

Object.prototype.del=function(){
this.death=true
for (var i in _root) {
if (_root[i].death){
delete _root[i]
}
}
}
есть два слабых места:
1) объект может лежать вовсе не на _root, а так как свойства _parent у объекта нет, придется искать его какой-нибудь рекурсией
2) может случиться перекрытие имен с death - а вдруг у объекта уже есть смысловая переменная с таким же именем?

GFreemen 06.05.2008 01:09

а если так
Код:

var zz1:Object={};
zz={};
zz.qwe=function(){
        kill(this);
}
function kill (asd) {
        for(var i in this){
                if(this[i]===asd){
                        delete this[i];
                        trace(i+"  "+this[i]);//zz  undefined
                }
        }
}
zz.qwe();
trace("end "+zz);//end undefined
trace("end1 "+zz1);//end1 [object Object]


wvxvw 06.05.2008 10:57

Объекты не должны сами себя удалять, это ошибка в дизайне...

chingachgoog 06.05.2008 12:35

Цитата:

Сообщение от GFreemen (Сообщение 737363)
а если так

Та же дыня только сбоку :)

Код:

...
function kill (asd) {
        trace("this="+this)
        for(var i in this){
                trace("i="+i+" this[i]="+this[i])
                if(this[i]===asd){
                        delete this[i];
                        trace(i+"  "+this[i]);//zz  undefined
                }
        }
}
...

Т.е. this в данном случае - это тот же _root или любая другая временная диаграмма где находиться метод kill и объект (они должны находиться на одной временной диаграмме). В этом то и главная засада, что объект не знает где он находиться :(
Но хорошо, что проблема с перекрыванием имен оказалась надуманной мной - переменная типа death не требуется:
Код:

Object.prototype.del=function(){
        //this.death=true
        for (var i in _root) {
                if (_root[i]==this){
                        delete _root[i]
                }
        }
}

zz={}
zz.prop="qwerty"
trace(zz+" "+zz.prop)

zz.del()
trace(zz+" "+zz.prop)


Цитата:

Сообщение от wvxvw
Объекты не должны сами себя удалять, это ошибка в дизайне...

А что тут криминального? По-моему вполне законное и удобное желание. Тем более что они МОГУТ себя удалять - только не знают где они находяться.

add:
Не люблю рекурсию, но пока ничего иного не придумал:

Код:

Object.prototype.del=function(path, firstThis){
        if(arguments.caller==null){
                var parent=_root
                var firstThis=this
        } else {
                var parent=path
                var firstThis=firstThis
        }
       
        for (var i in parent) {
                if (parent[i]==firstThis){
                        delete parent[i]
                        return null                       
                }
                if (typeof(parent[i])=='movieclip' || typeof(parent[i])=='object'){
                        if (arguments.callee(parent[i], firstThis)==null){
                                return null
                        }
                }
        }
       
        for (var i in _global) {
                if (_global[i]==firstThis){
                        delete _global[i]
                        return null                       
                }
                if (typeof(_global[i])=='movieclip' || typeof(_global[i])=='object'){
                        if (arguments.callee(_global[i], firstThis)==null){
                                return null
                        }
                }
        }
}

Вроде убивает все и вся.

alexcon314 06.05.2008 14:02

>>Тем более что они МОГУТ себя удалять ..
во всех приведенных примерах, насколько я смог понять, экземпляры объектов НЕ УДАЛЯЮТ САМИ СЕБЯ, что они делать не могут и не должны по определению. А отдать другому объекту-киллеру ссылку на себя с призывом "вот он я, убей меня быстрее!" - что тут заморочного? всегда так и делают в принципе. то что в прототипе вы прописываете метод del, ничего не меняет по сути, только вносит путаницу и все.

chingachgoog 06.05.2008 14:08

Цитата:

Сообщение от alexcon314 (Сообщение 737455)
>>Тем более что они МОГУТ себя удалять ..
во всех приведенных примерах, насколько я смог понять, экземпляры объектов НЕ УДАЛЯЮТ САМИ СЕБЯ, что они делать не могут и не должны по определению. А отдать другому объекту-киллеру ссылку на себя с призывом "вот он я, убей меня быстрее!" - что тут заморочного? всегда так и делают в принципе.

В этом случае можно сказать, что и мой_мувик в коде
Код:

мой_мувик.removeMovieClip()
не удаляет сам себя а лишь отдает другому объекту (команде) киллеру ссылку на себя с призывом "вот он я, убей меня быстрее!"
А замороченного тут только то, что объект не знает ни своего имени ни своего родителя.

Цитата:

Сообщение от alexcon314 (Сообщение 737455)
>>то что в прототипе вы прописываете метод del, ничего не меняет по сути, только вносит путаницу и все.

В чем путаница не понял?

Vertax 06.05.2008 14:29

Развивая мысль, может так:
Код:

Object.prototype.del=function(LVL)
{
        if (LVL == undefined) LVL = _root;
        for (var i in LVL)
        {
                if (LVL[i] == this){delete LVL[i]; return true;}
                else if (typeof(LVL[i]) != "function" && this.del(LVL[i])){return true;}
        }
        return false;
}

mc = _root.createEmptyMovieClip("aaa", 1);
mc.zz = {};
mc.zz.prop="qwerty";
trace(mc.zz+" "+mc.zz.prop);

mc.zz.del();
trace(mc.zz+" "+mc.zz.prop);


chingachgoog 06.05.2008 14:44

Цитата:

Сообщение от Vertax (Сообщение 737463)
Развивая мысль, может так:

Можно и так, если поставить уловитель _global и отсекатель элементарных данных (строки, булевые величины и числа)

Vertax 06.05.2008 15:42

Цитата:

Можно и так, если поставить уловитель _global
Код:

Object.prototype.del=function(LVL)
{
        if (LVL == undefined)
        {
                LVL = _root;
                for (var i in _global) if (_global[i] == this){delete _global[i]; return true;}
        }
        for (var i in LVL)
        {
                if (LVL[i] == this){delete LVL[i]; return true;}
                else if (typeof(LVL[i]) != "function" && this.del(LVL[i])){return true;}
        }
        return false;
}

Цитата:

и отсекатель элементарных данных (строки, булевые величины и числа)
Не согласен, т.к. они будут только усложнять конструкцию.

Недостаток в коллекцию:
Код:

a = {};
a.OBJ = "Hello";

b = {};
b.parent = _root;

a.del();


wvxvw 06.05.2008 16:09

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

chingachgoog 06.05.2008 16:32

Не, Vertax, у вас глобал не отлавливает
Код:

_global.z={}
z.ss={}
trace(z+" "+z.ss)
z.ss.del()
trace(z+" "+z.ss)

Цитата:

Сообщение от Vertax (Сообщение 737475)
[code]
Недостаток в коллекцию:
Код:

a = {};
a.OBJ = "Hello";

b = {};
b.parent = _root;

a.del();


Поэтому я и не люблю рекурсию :)
add:
Но кажется я победил зацикливание по ссылке на другой объект:

Код:

Object.prototype.del=function(path, firstThis){
        if(arguments.caller==null){
                var parent=_root
                var firstThis=this
        } else {
                var parent=path
                var firstThis=firstThis
        }
        for (var i in parent) {
                if (parent[i]==firstThis){
                        delete parent[i]
                        return null                       
                }
                if (typeof(parent[i])=='movieclip' || typeof(parent[i])=='object' && typeof(i)==string){
                        var rez=arguments.callee(parent[i], firstThis)
                        if (rez==null){
                                return null
                        }
                }
        }
        if(arguments.caller==null){
                for (var i in _global) {
                        if (_global[i]==firstThis){
                                delete _global[i]
                                return null                       
                        }
                        if (typeof(_global[i])=='movieclip' || typeof(_global[i])=='object'){
                                if (arguments.callee(_global[i], firstThis)==null){
                                        return null
                                }
                        }
                }
        } else {
                return false
        }
}


iNils 06.05.2008 21:03

Цитата:

Сообщение от chingachgoog (Сообщение 737458)
В этом случае можно сказать, что и мой_мувик в коде
Код:

мой_мувик.removeMovieClip()
не удаляет сам себя а лишь отдает другому объекту (команде) киллеру ссылку на себя с призывом "вот он я, убей меня быстрее!"

Мувиклип, это визуальный объект, у него своя логика поведения, он даже не через new создается.

chingachgoog 07.05.2008 10:09

Я просто хотел сказать, что в этой логике получается, что ни один объект, включая мувиклип, себя напрямую не убивает - все равно идет обращение к команде-киллеру (встроенной или внешней). Но я всего-лишь хотел сделать аналог removeMovieClip(), но только для объектов.

iNils 07.05.2008 10:51

А сделать delete для мувиклипа нет желание? :D

AL.exe 07.05.2008 18:34

Цитата:

Сообщение от wvxvw (Сообщение 737405)
Объекты не должны сами себя удалять, это ошибка в дизайне...

Ну, почему... если объект мувиклип - то это, имхо, оправданно. Но мувиклип спокойно себя удаляет ( removeMovieClip() ).

Пример использования - программная анимация частиц, когда мувиклипы аттачаться на сцену и умирают, когда проигрывают свою анимацию.

crazyone 07.05.2008 19:25

Надеюсь бить меня никто не будет, если я напомню, что в ас2 объекты вручную вообще удалить нельзя?
Можно удалить все ссылки на него из-вне, тогда он убивается автоматически.

upd
В связи с этим все недовольства по поводу того, что вызывается delete %имя_объекта% — беспомощны.

В связи с этим максимум, что можно сделать — покрутить вариант, предложеный iNils на первой странице. Например так:
Код:

this.createObj=function (name) {
        this[name]=new Object();
        this[name]name=name;
        this[name]parent=this;
        this[name].del=function(){
            delete this.parent[this.name];
        }
}

this.createObj("obj1");
trace(this.obj1);
this.obj1.del();
trace(this.obj1);

И то - это только удалит ту ссылку, которая вернулась при создании объекта. Тоесть - мечты-мечты... Если можно обойтись без этого - нужно обходиться без этого. Ура!


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

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