Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Объектная модель


Автор: maxkazar 3.12.2004, 12:29
Необходимо в объекте использовать задержку(таймер) window.setTimeout().
Например:
Код

function Test() {
 this.Action = fnAction
 this.SetTimer = fnSetTimer
 this.Name = "Test"

 function fnAction() {
   alert(this.Test)
 }

 function fnSetTimer() {
   setTimerout("this.Action()",1000)
 }

}

var T = new Test()
T.SetTimer()



Вот так бы хотелось в идеале....но к сожалению так не получится(. Т.к. вызов функции таймера (в примере this.Action() ) происходит в конетксте основного объекта (если я не ошибаюсь это будет объект window). Соответсвенно возникнет ошибка!. А как же тогда быть....как поставить таймер в объекте. Как сделать чтоб в обработчике таймера можно было использовать свойтва и методы самого объекта....

Мне в голову приходит только один способ....где-то надо хранить имя объекта (в примере T) а потом уже в обработчике получать ссылку на имя....но это полный геморой (очень далеко от идела!)

Автор: Sardar 3.12.2004, 14:58
maxkazar да это проблема, которая и меня порой достает...
window.setTimeout всегда исполняет функцию в контексте window. Я писал два решения, первое прописать всем функциям ссылку на обéкт:
Код

function myObj(n) {
this.test=n;

this.bla=function() {
  alert(arguments.callee.target.test); //берем переменную по ссылке на обьект
};
this.bla.target=this; //ссылка на обьект

this.timetest=function() {
   window.setTimeout(this.bla,1000); //ставим обычный таймер
}
}

var m=new myObj(34);
m.timetest();
var m=new myObj(100);
m.timetest();

Недаостаток что нужно всегда определять функции в конструкторе, что бы у каждого обьекта был свой обьект функция держущая ссылку на обьект target. Также ссылка arguments.callee по моему не существуетв ИЕ5.0

Можно завести регистр обьектов, в который будем складывать всех кто обратился на паузу:
Код
function myObj(n) {
this.test=n;
this.bla=function() {alert(this.test);};

this.timetest2=function() {
  window.setTimerout(this, "bla", 1000);
}
}

setTimerout.targets={};
function setTimerout(obj, func, time) {
 var uname="~" + Math.random(); //имя должно быть уникальным, сделал по быстрому, перепиши
 setTimerout.targets[uname]={tg:obj,fn:func};
 window.setTimeout("runTimerout('"+uname+"');", time); //вызываем нашь обработчик с ИД обьекта
}
function runTimerout(id) {
 if(typeof(setTimerout.targets[id])=="object") {
   var r=setTimerout.targets[id];
   delete setTimerout.targets[id];
   r.tg[r.fn](); //так будет работать везде
//    r.fn.call(r.tg); //если передавать не имя а функцию, но так не будет работать в ИЕ5.0
 }
}


var m=new myObj(34);
m.timetest2();
var m=new myObj(100);
m.timetest2();


Можно еще извратится, главное не уйти слишком далеко smile

Автор: maxkazar 3.12.2004, 15:18
Вот жешь....все гениально и просто, как это я сам не догадался... Просто в самом объекте надо хранить сылку на сам объект!....это вполне нормально....я данный подход использовал и раньше вот только здесь не попробывал))

Автор: Се ля ви 3.12.2004, 20:57
Господа, а почему бы не передавать ссылку на объект как параметр функции? Это конечно тоже кривовато, но всё-таки красифше и универсальней:
Код

m.Action(m);

Разве не меньшее из зол?

Автор: Sardar 4.12.2004, 00:42
Цитата
Разве не меньшее из зол?

И так тоже будет работать, просто выглядеит ну совсем не как ООП... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)