PDA

View Full Version : Custom object and calling its method continously in constructor function


WA
11-19-2002, 05:53 AM
Hi:
I have a question regarding using setTimeout/setInterval inside a constructor function to repeatedly call one of its methods- for some reason I can't get it to work. For example:

function myconstructor(){
setInterval("this.doit()",100)
}

myconstructor.prototype.doit=function(){
window.status="test"
}

var testobj=new myconstructor()

I feel like I'm missing something obvious (hopefully).

Thanks for any help.

glenngv
11-19-2002, 06:32 AM
if the constructor function is a "normal" contructor, this would achieve the same effect:

var testobj=new myconstructor();
setTimeout("testobj.doit()",100);

but since you want to automatically execute the doit() method once an object is instantiated, you could change the constructor like this:

function myconstructor(objname){
setTimeout(objname+".doit()",100)
}
var testobj=new myconstructor("testobj")
var testobj2=new myconstructor("testobj2")

not pretty though :D
maybe there's a better solution.

WA
11-19-2002, 07:08 AM
Thanks glenngv. Yep, I'm specifically looking for a solution that would repeatedly call one of the constructor's method automatically upon instantiating it, and inside it. I'll try and find a sample script where I believe I've seen this done once.

glenngv
11-19-2002, 08:09 AM
does my solution work the way you want it to?

if you don't want to call setTimeout twice (since you want it to be called repeatedly), use setInterval instead. I'm sure you know that, just feel like mentioning it :D

Algorithm
11-19-2002, 09:18 AM
From the Netscape JavaScript 1.3 documentation (http://developer.netscape.com/docs/manuals/js/client/jsref/window.htm#1203669):

setInterval(function, msec[, arg1[, ..., argN]])

Parameters

function
Any function.

msec
A numeric value or numeric string, in millisecond units.

arg1, ..., argn
The arguments, if any, passed to function.

Hope that helps, haven't tried it.

WA
11-19-2002, 12:03 PM
Originally posted by glenngv
does my solution work the way you want it to?

Hi Glenn:
Unfortunately I was hoping for a solution that would internalize everything, rather than have to explicity pass in the object to the object itself.

The problem would seem to be the part in bold:

setInterval("this.doit()",100)

this.doit() loses its reference as soon as it's passed into setInterval or setTimeout. There has to be a way to retain this reference while still upholding OOP.

A script that seems to have successfully done this is Mike's DHTML scroller (http://www.dynamicdrive.com/dynamicindex2/mikescroll.htm). The scrolling aspect obviously requires setInterval/setTimeout, though everything is encapsulated in the user defined object/class.

glenngv
11-19-2002, 12:30 PM
I can't find any property that corresponds to the name of the calling object.

function myconstructor(){
for (var i in this) alert(i +" : " + this[i])
//setTimeout("this.doit()",100)
}

that's why I think the only way may be to pass the object name to the constructor

joh6nn
11-19-2002, 07:13 PM
here's the beginning of the constructor function from mike's scroller:

function scrollerCreate() {

var start, end;
var str;
var i, j;
var x, y;

if (!isMinNS4 && !ie && !dom)
return;

// On first scroller, start interval timer.

if (scrollerList.length == 0)
setInterval('scrollerGo()', scrollerInterval);


he's not calling a method of the object, but rather a global function.

if i remember correctly, setTimeout() and setInterval(), are like eval(), in that they execute code at the global level. so, setInterval("this.doit()",100), can't work, because "this" will refer to the window. the only way to make it work, that i know of, is the way that glenn suggested.

hope that helps.

Roy Sinclair
11-19-2002, 09:33 PM
I think Glennv might have been close, one of the properties for any object should be it's name so:

function myconstructor(objname){
setTimeout(this.name+".doit()",100)
}

or something similar might do the trick (perhaps this.id?).

WA
11-19-2002, 11:55 PM
Thanks guys. I did notice Mike's code seemed to be calling a global function as well, though I believe there's more to it. The scroller in this case still turns out to be completely self encapsulating, without the multiple setIntervals stepping on one another (when the user defines multiple scrollers on the same page). A straightforward call to a global function using setInterval would have destroyed this.

In fact, I believe I've just found a better example that shows how it's possible to use setTimeout/setInterval inside a custom object to repeatedly call its method: http://javascript-fx.com/newstickers/index.html Unfortunately you'll need to actually download and see the two .js files to see this in action. I'm still trying to decipher how it was done, however.

glenngv
11-20-2002, 12:38 AM
Originally posted by Roy Sinclair
I think Glennv might have been close, one of the properties for any object should be it's name so:

function myconstructor(objname){
setTimeout(this.name+".doit()",100)
}

or something similar might do the trick (perhaps this.id?).

I've tried that before and this.name or this.id returns undefined.

and if you instantiate a new instance from this constructor, you can find the properties of this and it turns out to be only one (but actually it's a function not property).

function myconstructor(){
for (var i in this) alert(i +" : " + this[i])
}
myconstructor.prototype.doit=function(){
window.status="test";
}

var testobj = new myconstructor();

the alert will say:

doit : function(){
window.status="test";
}

Algorithm
11-20-2002, 04:09 AM
This has been bugging me, so I built this object to solve the problem. You still can't pass local functions, but you can pass local object references, and that should be enough. :)

edit: I now have a much-improved version of this code available in the Posted Javascripts forum. Check it out here (http://www.codingforums.com/showthread.php?s=&threadid=10531).